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)
 
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)
 

Function Documentation

◆ BaseInit()

void BaseInit ( void  )

Definition at line 607 of file postinit.c.

608{
609 Assert(MyProc != NULL);
610
611 /*
612 * Initialize our input/output/debugging file descriptors.
613 */
615
616 /*
617 * Initialize file access. Done early so other subsystems can access
618 * files.
619 */
621
622 /*
623 * Initialize statistics reporting. This needs to happen early to ensure
624 * that pgstat's shutdown callback runs after the shutdown callbacks of
625 * all subsystems that can produce stats (like e.g. transaction commits
626 * can).
627 */
629
630 /*
631 * Initialize AIO before infrastructure that might need to actually
632 * execute AIO.
633 */
635
636 /* Do local initialization of storage and buffer managers */
637 InitSync();
638 smgrinit();
640
641 /*
642 * Initialize temporary file access after pgstat, so that the temporary
643 * file shutdown hook can report temporary file statistics.
644 */
646
647 /*
648 * Initialize local buffers for WAL record construction, in case we ever
649 * try to insert XLOG.
650 */
652
653 /* Initialize lock manager's local structs */
655
656 /* Initialize logical info WAL logging state */
658
659 /*
660 * Initialize replication slots after pgstat. The exit hook might need to
661 * drop ephemeral slots, which in turn triggers stats reporting.
662 */
664}
void pgaio_init_backend(void)
Definition aio_init.c:218
void InitBufferManagerAccess(void)
Definition bufmgr.c:4120
#define Assert(condition)
Definition c.h:873
void DebugFileOpen(void)
Definition elog.c:2128
void InitFileAccess(void)
Definition fd.c:900
void InitTemporaryFileAccess(void)
Definition fd.c:930
void InitLockManagerAccess(void)
Definition lock.c:505
void InitializeProcessXLogLogicalInfo(void)
Definition logicalctl.c:176
void pgstat_initialize(void)
Definition pgstat.c:651
static int fb(int x)
void ReplicationSlotInitialize(void)
Definition slot.c:241
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 323 of file postinit.c.

324{
327 Datum datum;
328 bool isnull;
329 char *collate;
330 char *ctype;
331
332 /* Fetch our pg_database row normally, via syscache */
334 if (!HeapTupleIsValid(tup))
335 elog(ERROR, "cache lookup failed for database %u", MyDatabaseId);
337
338 /* This recheck is strictly paranoia */
339 if (strcmp(name, NameStr(dbform->datname)) != 0)
342 errmsg("database \"%s\" has disappeared from pg_database",
343 name),
344 errdetail("Database OID %u now seems to belong to \"%s\".",
345 MyDatabaseId, NameStr(dbform->datname))));
346
347 /*
348 * Check permissions to connect to the database.
349 *
350 * These checks are not enforced when in standalone mode, so that there is
351 * a way to recover from disabling all access to all databases, for
352 * example "UPDATE pg_database SET datallowconn = false;".
353 */
355 {
356 /*
357 * Check that the database is currently allowing connections.
358 * (Background processes can override this test and the next one by
359 * setting override_allow_connections.)
360 */
361 if (!dbform->datallowconn && !override_allow_connections)
364 errmsg("database \"%s\" is not currently accepting connections",
365 name)));
366
367 /*
368 * Check privilege to connect to the database. (The am_superuser test
369 * is redundant, but since we have the flag, might as well check it
370 * and save a few cycles.)
371 */
377 errmsg("permission denied for database \"%s\"", name),
378 errdetail("User does not have CONNECT privilege.")));
379
380 /*
381 * Check connection limit for this database. We enforce the limit
382 * only for regular backends, since other process types have their own
383 * PGPROC pools.
384 *
385 * There is a race condition here --- we create our PGPROC before
386 * checking for other PGPROCs. If two backends did this at about the
387 * same time, they might both think they were over the limit, while
388 * ideally one should succeed and one fail. Getting that to work
389 * exactly seems more trouble than it is worth, however; instead we
390 * just document that the connection limit is approximate.
391 */
392 if (dbform->datconnlimit >= 0 &&
394 !am_superuser &&
395 CountDBConnections(MyDatabaseId) > dbform->datconnlimit)
398 errmsg("too many connections for database \"%s\"",
399 name)));
400 }
401
402 /*
403 * OK, we're golden. Next to-do item is to save the encoding info out of
404 * the pg_database tuple.
405 */
406 SetDatabaseEncoding(dbform->encoding);
407 /* Record it as a GUC internal option, too */
408 SetConfigOption("server_encoding", GetDatabaseEncodingName(),
410 /* If we have no other source of client_encoding, use server encoding */
411 SetConfigOption("client_encoding", GetDatabaseEncodingName(),
413
414 /* assign locale variables */
416 collate = TextDatumGetCString(datum);
418 ctype = TextDatumGetCString(datum);
419
420 /*
421 * Historically, we set LC_COLLATE from datcollate, as well. That's no
422 * longer necessary because all collation behavior is handled through
423 * pg_locale_t.
424 */
425
426 if (pg_perm_setlocale(LC_CTYPE, ctype) == NULL)
428 (errmsg("database locale is incompatible with operating system"),
429 errdetail("The database was initialized with LC_CTYPE \"%s\", "
430 " which is not recognized by setlocale().", ctype),
431 errhint("Recreate the database with another locale or install the missing locale.")));
432
434
435 /*
436 * Check collation version. See similar code in
437 * pg_newlocale_from_collation(). Note that here we warn instead of error
438 * in any case, so that we don't prevent connecting.
439 */
441 &isnull);
442 if (!isnull)
443 {
444 char *actual_versionstr;
445 char *collversionstr;
446 char *locale;
447
449
450 if (dbform->datlocprovider == COLLPROVIDER_LIBC)
451 locale = collate;
452 else
453 {
455 locale = TextDatumGetCString(datum);
456 }
457
458 actual_versionstr = get_collation_actual_version(dbform->datlocprovider, locale);
460 /* should not happen */
462 "database \"%s\" has no actual collation version, but a version was recorded",
463 name);
466 (errmsg("database \"%s\" has a collation version mismatch",
467 name),
468 errdetail("The database was created using collation version %s, "
469 "but the operating system provides version %s.",
471 errhint("Rebuild all objects in this database that use the default collation and run "
472 "ALTER DATABASE %s REFRESH COLLATION VERSION, "
473 "or build PostgreSQL with the right library version.",
475 }
476
478}
@ ACLCHECK_OK
Definition acl.h:183
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
Definition aclchk.c:3836
#define TextDatumGetCString(d)
Definition builtins.h:98
#define NameStr(name)
Definition c.h:765
int errdetail(const char *fmt,...)
Definition elog.c:1216
int errhint(const char *fmt,...)
Definition elog.c:1330
int errcode(int sqlerrcode)
Definition elog.c:863
int errmsg(const char *fmt,...)
Definition elog.c:1080
#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:1270
void SetDatabaseEncoding(int encoding)
Definition mbutils.c:1164
#define AmRegularBackendProcess()
Definition miscadmin.h:381
Oid GetUserId(void)
Definition miscinit.c:469
#define ACL_CONNECT
Definition parsenodes.h:87
FormData_pg_database * Form_pg_database
Definition pg_database.h:96
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:3590
const char * quote_identifier(const char *ident)
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:264
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition syscache.c:220
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition syscache.c:595
Datum SysCacheGetAttrNotNull(int cacheId, HeapTuple tup, AttrNumber attributeNumber)
Definition syscache.c:625
const char * name

References ACL_CONNECT, ACLCHECK_OK, AmRegularBackendProcess, CountDBConnections(), elog, ereport, errcode(), errdetail(), errhint(), errmsg(), ERROR, FATAL, fb(), 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 1422 of file postinit.c.

1423{
1425 InterruptPending = true;
1427}
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().

◆ GetDatabaseTuple()

static HeapTuple GetDatabaseTuple ( const char dbname)
static

Definition at line 105 of file postinit.c.

106{
107 HeapTuple tuple;
108 Relation relation;
109 SysScanDesc scan;
110 ScanKeyData key[1];
111
112 /*
113 * form a scan key
114 */
115 ScanKeyInit(&key[0],
119
120 /*
121 * Open pg_database and fetch a tuple. Force heap scan if we haven't yet
122 * built the critical shared relcache entries (i.e., we're starting up
123 * without a shared relcache cache file).
124 */
128 NULL,
129 1, key);
130
131 tuple = systable_getnext(scan);
132
133 /* Must copy tuple before releasing buffer */
134 if (HeapTupleIsValid(tuple))
135 tuple = heap_copytuple(tuple);
136
137 /* all done */
138 systable_endscan(scan);
139 table_close(relation, AccessShareLock);
140
141 return tuple;
142}
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 148 of file postinit.c.

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

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

1399{
1401 InterruptPending = true;
1403}
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 1406 of file postinit.c.

1407{
1409 InterruptPending = true;
1411}
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 1414 of file postinit.c.

1415{
1417 InterruptPending = true;
1419}
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 575 of file postinit.c.

576{
577 /* Should be initialized only once. */
579
580 /*
581 * Based on the max_locks_per_transaction GUC, as that's a good indicator
582 * of the expected number of locks, figure out the value for
583 * FastPathLockGroupsPerBackend. This must be a power-of-two. We cap the
584 * value at FP_LOCK_GROUPS_PER_BACKEND_MAX and insist the value is at
585 * least 1.
586 *
587 * The default max_locks_per_transaction = 64 means 4 groups by default.
588 */
592
593 /* Validate we did get a power-of-two */
596}
#define Min(x, y)
Definition c.h:997
#define Max(x, y)
Definition c.h:991
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:91
#define FP_LOCK_SLOTS_PER_GROUP
Definition proc.h:92

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

551{
552 Assert(MaxBackends == 0);
553
554 /* Note that this does not include "auxiliary" processes */
557
561 errmsg("too many server processes configured"),
562 errdetail("\"max_connections\" (%d) plus \"autovacuum_worker_slots\" (%d) plus \"max_worker_processes\" (%d) plus \"max_wal_senders\" (%d) must be less than %d.",
566}
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:456
#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 710 of file postinit.c.

714{
716 bool am_superuser;
717 char *fullpath;
718 char dbname[NAMEDATALEN];
719 int nfree = 0;
720
721 elog(DEBUG3, "InitPostgres");
722
723 /*
724 * Add my PGPROC struct to the ProcArray.
725 *
726 * Once I have done this, I am visible to other backends!
727 */
729
730 /* Initialize status reporting */
732
733 /*
734 * And initialize an entry in the PgBackendStatus array. That way, if
735 * LWLocks or third-party authentication should happen to hang, it is
736 * possible to retrieve some information about what is going on.
737 */
738 if (!bootstrap)
739 {
741 INJECTION_POINT("init-pre-auth", NULL);
742 }
743
744 /*
745 * Initialize my entry in the shared-invalidation manager's array of
746 * per-backend data.
747 */
749
751
752 /*
753 * Also set up timeout handlers needed for backend operation. We need
754 * these in every case except bootstrap.
755 */
756 if (!bootstrap)
757 {
768 }
769
770 /*
771 * If this is either a bootstrap process or a standalone backend, start up
772 * the XLOG machinery, and register to have it closed down at exit. In
773 * other cases, the startup process is responsible for starting up the
774 * XLOG machinery, and the checkpointer for closing it down.
775 */
777 {
778 /*
779 * We don't yet have an aux-process resource owner, but StartupXLOG
780 * and ShutdownXLOG will need one. Hence, create said resource owner
781 * (and register a callback to clean it up after ShutdownXLOG runs).
782 */
784
785 StartupXLOG();
786 /* Release (and warn about) any buffer pins leaked in StartupXLOG */
788 /* Reset CurrentResourceOwner to nothing for the moment */
790
791 /*
792 * Use before_shmem_exit() so that ShutdownXLOG() can rely on DSM
793 * segments etc to work (which in turn is required for pgstats).
794 */
797 }
798
799 /*
800 * Initialize the relation cache and the system catalog caches. Note that
801 * no catalog access happens here; we only set up the hashtable structure.
802 * We must do this before starting a transaction because transaction abort
803 * would try to touch these hashtables.
804 */
808
809 /* Initialize portal manager */
811
812 /*
813 * Load relcache entries for the shared system catalogs. This must create
814 * at least entries for pg_database and catalogs used for authentication.
815 */
817
818 /*
819 * Set up process-exit callback to do pre-shutdown cleanup. This is one
820 * of the first before_shmem_exit callbacks we register; thus, this will
821 * be one of the last things we do before low-level modules like the
822 * buffer manager begin to close down. We need to have this in place
823 * before we begin our first transaction --- if we fail during the
824 * initialization transaction, as is entirely possible, we need the
825 * AbortTransaction call to clean up.
826 */
828
829 /* The autovacuum launcher is done here */
831 {
832 /* fill in the remainder of this entry in the PgBackendStatus array */
834
835 return;
836 }
837
838 /*
839 * Start a new transaction here before first access to db.
840 */
841 if (!bootstrap)
842 {
843 /* statement_timestamp must be set for timeouts to work correctly */
846
847 /*
848 * transaction_isolation will have been set to the default by the
849 * above. If the default is "serializable", and we are in hot
850 * standby, we will fail if we don't change it to something lower.
851 * Fortunately, "read committed" is plenty good enough.
852 */
854 }
855
856 /*
857 * Perform client authentication if necessary, then figure out our
858 * postgres user ID, and see if we are a superuser.
859 *
860 * In standalone mode, autovacuum worker processes and slot sync worker
861 * process, we use a fixed ID, otherwise we figure it out from the
862 * authenticated user name.
863 */
865 {
867 am_superuser = true;
868 }
869 else if (!IsUnderPostmaster)
870 {
872 am_superuser = true;
876 errmsg("no roles are defined in this database system"),
877 errhint("You should immediately run CREATE USER \"%s\" SUPERUSER;.",
878 username != NULL ? username : "postgres")));
879 }
880 else if (AmBackgroundWorkerProcess())
881 {
882 if (username == NULL && !OidIsValid(useroid))
883 {
885 am_superuser = true;
886 }
887 else
888 {
890 (flags & INIT_PG_OVERRIDE_ROLE_LOGIN) != 0);
892 }
893 }
894 else
895 {
896 /* normal multiuser case */
900 /* ensure that auth_method is actually valid, aka authn_id is not NULL */
905 }
906
907 /* Report any SSL/GSS details for the session. */
908 if (MyProcPort != NULL)
909 {
911
913 }
914
915 /*
916 * Binary upgrades only allowed super-user connections
917 */
919 {
922 errmsg("must be superuser to connect in binary upgrade mode")));
923 }
924
925 /*
926 * The last few regular connection slots are reserved for superusers and
927 * roles with privileges of pg_use_reserved_connections. We do not apply
928 * these limits to background processes, since they all have their own
929 * pools of PGPROC slots.
930 *
931 * Note: At this point, the new backend has already claimed a proc struct,
932 * so we must check whether the number of free slots is strictly less than
933 * the reserved connection limits.
934 */
938 {
942 errmsg("remaining connection slots are reserved for roles with the %s attribute",
943 "SUPERUSER")));
944
948 errmsg("remaining connection slots are reserved for roles with privileges of the \"%s\" role",
949 "pg_use_reserved_connections")));
950 }
951
952 /* Check replication permissions needed for walsender processes. */
953 if (am_walsender)
954 {
956
960 errmsg("permission denied to start WAL sender"),
961 errdetail("Only roles with the %s attribute may start a WAL sender process.",
962 "REPLICATION")));
963 }
964
965 /*
966 * If this is a plain walsender only supporting physical replication, we
967 * don't want to connect to any particular database. Just finish the
968 * backend startup by processing any options from the startup packet, and
969 * we're done.
970 */
972 {
973 /* process any options passed in the startup packet */
974 if (MyProcPort != NULL)
976
977 /* Apply PostAuthDelay as soon as we've read all options */
978 if (PostAuthDelay > 0)
979 pg_usleep(PostAuthDelay * 1000000L);
980
981 /* initialize client encoding */
983
984 /* fill in the remainder of this entry in the PgBackendStatus array */
986
987 /* close the transaction we started above */
989
990 return;
991 }
992
993 /*
994 * Set up the global variables holding database id and default tablespace.
995 * But note we won't actually try to touch the database just yet.
996 *
997 * We take a shortcut in the bootstrap case, otherwise we have to look up
998 * the db's entry in pg_database.
999 */
1000 if (bootstrap)
1001 {
1002 dboid = Template1DbOid;
1004 }
1005 else if (in_dbname != NULL)
1006 {
1007 HeapTuple tuple;
1009
1010 tuple = GetDatabaseTuple(in_dbname);
1011 if (!HeapTupleIsValid(tuple))
1012 ereport(FATAL,
1014 errmsg("database \"%s\" does not exist", in_dbname)));
1016 dboid = dbform->oid;
1017 }
1018 else if (!OidIsValid(dboid))
1019 {
1020 /*
1021 * If this is a background worker not bound to any particular
1022 * database, we're done now. Everything that follows only makes sense
1023 * if we are bound to a specific database. We do need to close the
1024 * transaction we started before returning.
1025 */
1026 if (!bootstrap)
1027 {
1030 }
1031 return;
1032 }
1033
1034 /*
1035 * Now, take a writer's lock on the database we are trying to connect to.
1036 * If there is a concurrently running DROP DATABASE on that database, this
1037 * will block us until it finishes (and has committed its update of
1038 * pg_database).
1039 *
1040 * Note that the lock is not held long, only until the end of this startup
1041 * transaction. This is OK since we will advertise our use of the
1042 * database in the ProcArray before dropping the lock (in fact, that's the
1043 * next thing to do). Anyone trying a DROP DATABASE after this point will
1044 * see us in the array once they have the lock. Ordering is important for
1045 * this because we don't want to advertise ourselves as being in this
1046 * database until we have the lock; otherwise we create what amounts to a
1047 * deadlock with CountOtherDBBackends().
1048 *
1049 * Note: use of RowExclusiveLock here is reasonable because we envision
1050 * our session as being a concurrent writer of the database. If we had a
1051 * way of declaring a session as being guaranteed-read-only, we could use
1052 * AccessShareLock for such sessions and thereby not conflict against
1053 * CREATE DATABASE.
1054 */
1055 if (!bootstrap)
1057
1058 /*
1059 * Recheck pg_database to make sure the target database hasn't gone away.
1060 * If there was a concurrent DROP DATABASE, this ensures we will die
1061 * cleanly without creating a mess.
1062 */
1063 if (!bootstrap)
1064 {
1065 HeapTuple tuple;
1067
1068 tuple = GetDatabaseTupleByOid(dboid);
1069 if (HeapTupleIsValid(tuple))
1071
1072 if (!HeapTupleIsValid(tuple) ||
1073 (in_dbname && namestrcmp(&datform->datname, in_dbname)))
1074 {
1075 if (in_dbname)
1076 ereport(FATAL,
1078 errmsg("database \"%s\" does not exist", in_dbname),
1079 errdetail("It seems to have just been dropped or renamed.")));
1080 else
1081 ereport(FATAL,
1083 errmsg("database %u does not exist", dboid)));
1084 }
1085
1086 strlcpy(dbname, NameStr(datform->datname), sizeof(dbname));
1087
1089 {
1090 ereport(FATAL,
1092 errmsg("cannot connect to invalid database \"%s\"", dbname),
1093 errhint("Use DROP DATABASE to drop invalid databases."));
1094 }
1095
1096 MyDatabaseTableSpace = datform->dattablespace;
1097 MyDatabaseHasLoginEventTriggers = datform->dathasloginevt;
1098 /* pass the database name back to the caller */
1099 if (out_dbname)
1101 }
1102
1103 /*
1104 * Now that we rechecked, we are certain to be connected to a database and
1105 * thus can set MyDatabaseId.
1106 *
1107 * It is important that MyDatabaseId only be set once we are sure that the
1108 * target database can no longer be concurrently dropped or renamed. For
1109 * example, without this guarantee, pgstat_update_dbstats() could create
1110 * entries for databases that were just dropped in the pgstat shutdown
1111 * callback, which could confuse other code paths like the autovacuum
1112 * scheduler.
1113 */
1114 MyDatabaseId = dboid;
1115
1116 /*
1117 * Now we can mark our PGPROC entry with the database ID.
1118 *
1119 * We assume this is an atomic store so no lock is needed; though actually
1120 * things would work fine even if it weren't atomic. Anyone searching the
1121 * ProcArray for this database's ID should hold the database lock, so they
1122 * would not be executing concurrently with this store. A process looking
1123 * for another database's ID could in theory see a chance match if it read
1124 * a partially-updated databaseId value; but as long as all such searches
1125 * wait and retry, as in CountOtherDBBackends(), they will certainly see
1126 * the correct value on their next try.
1127 */
1129
1130 /*
1131 * We established a catalog snapshot while reading pg_authid and/or
1132 * pg_database; but until we have set up MyDatabaseId, we won't react to
1133 * incoming sinval messages for unshared catalogs, so we won't realize it
1134 * if the snapshot has been invalidated. Assume it's no good anymore.
1135 */
1137
1138 /*
1139 * Now we should be able to access the database directory safely. Verify
1140 * it's there and looks reasonable.
1141 */
1143
1144 if (!bootstrap)
1145 {
1146 if (access(fullpath, F_OK) == -1)
1147 {
1148 if (errno == ENOENT)
1149 ereport(FATAL,
1151 errmsg("database \"%s\" does not exist",
1152 dbname),
1153 errdetail("The database subdirectory \"%s\" is missing.",
1154 fullpath)));
1155 else
1156 ereport(FATAL,
1158 errmsg("could not access directory \"%s\": %m",
1159 fullpath)));
1160 }
1161
1162 ValidatePgVersion(fullpath);
1163 }
1164
1165 SetDatabasePath(fullpath);
1166 pfree(fullpath);
1167
1168 /*
1169 * It's now possible to do real access to the system catalogs.
1170 *
1171 * Load relcache entries for the system catalogs. This must create at
1172 * least the minimum set of "nailed-in" cache entries.
1173 */
1175
1176 /* set up ACL framework (so CheckMyDatabase can check permissions) */
1178
1179 /*
1180 * Re-read the pg_database row for our database, check permissions and set
1181 * up database-specific GUC settings. We can't do this until all the
1182 * database-access infrastructure is up. (Also, it wants to know if the
1183 * user is a superuser, so the above stuff has to happen first.)
1184 */
1185 if (!bootstrap)
1187 (flags & INIT_PG_OVERRIDE_ALLOW_CONNS) != 0);
1188
1189 /*
1190 * Now process any command-line switches and any additional GUC variable
1191 * settings passed in the startup packet. We couldn't do this before
1192 * because we didn't know if client is a superuser.
1193 */
1194 if (MyProcPort != NULL)
1196
1197 /* Process pg_db_role_setting options */
1199
1200 /* Apply PostAuthDelay as soon as we've read all options */
1201 if (PostAuthDelay > 0)
1202 pg_usleep(PostAuthDelay * 1000000L);
1203
1204 /*
1205 * Initialize various default states that can't be set up until we've
1206 * selected the active user and gotten the right GUC settings.
1207 */
1208
1209 /* set default namespace search path */
1211
1212 /* initialize client encoding */
1214
1215 /* Initialize this backend's session state. */
1217
1218 /*
1219 * If this is an interactive session, load any libraries that should be
1220 * preloaded at backend start. Since those are determined by GUCs, this
1221 * can't happen until GUC settings are complete, but we want it to happen
1222 * during the initial transaction in case anything that requires database
1223 * access needs to be done.
1224 */
1225 if ((flags & INIT_PG_LOAD_SESSION_LIBS) != 0)
1227
1228 /* fill in the remainder of this entry in the PgBackendStatus array */
1229 if (!bootstrap)
1231
1232 /* close the transaction we started above */
1233 if (!bootstrap)
1235}
void initialize_acl(void)
Definition acl.c:5040
bool has_privs_of_role(Oid member, Oid role)
Definition acl.c:5284
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:788
bool database_is_invalid_form(Form_pg_database datform)
int errcode_for_file_access(void)
Definition elog.c:886
#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:282
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:4806
#define NAMEDATALEN
void pgstat_before_server_shutdown(int code, Datum arg)
Definition pgstat.c:572
void InitPlanCache(void)
Definition plancache.c:146
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:100
static void ShutdownPostgres(int code, Datum arg)
Definition postinit.c:1341
static void IdleInTransactionSessionTimeoutHandler(void)
Definition postinit.c:1398
static void LockTimeoutHandler(void)
Definition postinit.c:1380
static void IdleStatsUpdateTimeoutHandler(void)
Definition postinit.c:1414
static void process_settings(Oid databaseid, Oid roleid)
Definition postinit.c:1307
static void IdleSessionTimeoutHandler(void)
Definition postinit.c:1406
static void process_startup_options(Port *port, bool am_superuser)
Definition postinit.c:1242
static void StatementTimeoutHandler(void)
Definition postinit.c:1358
static void CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connections)
Definition postinit.c:323
static bool ThereIsAtLeastOneRole(void)
Definition postinit.c:1433
static void PerformAuthentication(Port *port)
Definition postinit.c:194
static void ClientCheckTimeoutHandler(void)
Definition postinit.c:1422
static HeapTuple GetDatabaseTuple(const char *dbname)
Definition postinit.c:105
static HeapTuple GetDatabaseTupleByOid(Oid dboid)
Definition postinit.c:148
static void TransactionTimeoutHandler(void)
Definition postinit.c:1390
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:166
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:787
void CheckDeadLockAlert(void)
Definition proc.c:1879
void InitProcessPhase2(void)
Definition proc.c:585
const char * authn_id
Definition libpq-be.h:99
Oid databaseId
Definition proc.h:224
bool superuser(void)
Definition superuser.c:46
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, EnablePortalManager(), ereport, errcode(), errcode_for_file_access(), errdetail(), errhint(), errmsg(), FATAL, fb(), 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 1380 of file postinit.c.

1381{
1382#ifdef HAVE_SETSID
1383 /* try to signal whole process group */
1385#endif
1387}
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 194 of file postinit.c.

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

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

1308{
1310 Snapshot snapshot;
1311
1312 if (!IsUnderPostmaster)
1313 return;
1314
1316
1317 /* read all the settings under the same snapshot for efficiency */
1319
1320 /* Later settings are ignored if set earlier. */
1322 ApplySetting(snapshot, InvalidOid, roleid, relsetting, PGC_S_USER);
1325
1326 UnregisterSnapshot(snapshot);
1328}
@ 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 1242 of file postinit.c.

1243{
1246
1248
1249 /*
1250 * First process any command-line switches that were included in the
1251 * startup packet, if we are in a regular backend.
1252 */
1253 if (port->cmdline_options != NULL)
1254 {
1255 /*
1256 * The maximum possible number of commandline arguments that could
1257 * come from port->cmdline_options is (strlen + 1) / 2; see
1258 * pg_split_opts().
1259 */
1260 char **av;
1261 int maxac;
1262 int ac;
1263
1264 maxac = 2 + (strlen(port->cmdline_options) + 1) / 2;
1265
1266 av = palloc_array(char *, maxac);
1267 ac = 0;
1268
1269 av[ac++] = "postgres";
1270
1271 pg_split_opts(av, &ac, port->cmdline_options);
1272
1273 av[ac] = NULL;
1274
1275 Assert(ac < maxac);
1276
1278 }
1279
1280 /*
1281 * Process any additional GUC variable settings passed in startup packet.
1282 * These are handled exactly like command-line variables.
1283 */
1284 gucopts = list_head(port->guc_options);
1285 while (gucopts)
1286 {
1287 char *name;
1288 char *value;
1289
1290 name = lfirst(gucopts);
1291 gucopts = lnext(port->guc_options, gucopts);
1292
1293 value = lfirst(gucopts);
1294 gucopts = lnext(port->guc_options, gucopts);
1295
1297 }
1298}
#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 @172 value
#define lfirst(lc)
Definition pg_list.h:172
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:3799
void pg_split_opts(char **argv, int *argcp, const char *optstr)
Definition postinit.c:492
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 1341 of file postinit.c.

1342{
1343 /* Make sure we've killed any active transaction */
1345
1346 /*
1347 * User locks are not released by transaction end, so be sure to release
1348 * them explicitly.
1349 */
1351}
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 1358 of file postinit.c.

1359{
1360 int sig = SIGINT;
1361
1362 /*
1363 * During authentication the timeout is used to deal with
1364 * authentication_timeout - we want to quit in response to such timeouts.
1365 */
1367 sig = SIGTERM;
1368
1369#ifdef HAVE_SETSID
1370 /* try to signal whole process group */
1371 kill(-MyProcPid, sig);
1372#endif
1373 kill(MyProcPid, sig);
1374}
static int sig
Definition pg_ctl.c:81

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

Referenced by InitPostgres().

◆ ThereIsAtLeastOneRole()

static bool ThereIsAtLeastOneRole ( void  )
static

Definition at line 1433 of file postinit.c.

1434{
1436 TableScanDesc scan;
1437 bool result;
1438
1440
1442 result = (heap_getnext(scan, ForwardScanDirection) != NULL);
1443
1444 table_endscan(scan);
1446
1447 return result;
1448}
HeapTuple heap_getnext(TableScanDesc sscan, ScanDirection direction)
Definition heapam.c:1409
@ 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:1005

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

1391{
1393 InterruptPending = true;
1395}
volatile sig_atomic_t TransactionTimeoutPending
Definition globals.c:38

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

Referenced by InitPostgres().