PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
postinit.c File Reference
#include "postgres.h"
#include <ctype.h>
#include <fcntl.h>
#include <unistd.h>
#include "access/heapam.h"
#include "access/htup_details.h"
#include "access/sysattr.h"
#include "access/xact.h"
#include "access/xlog.h"
#include "catalog/catalog.h"
#include "catalog/indexing.h"
#include "catalog/namespace.h"
#include "catalog/pg_authid.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/walsender.h"
#include "storage/bufmgr.h"
#include "storage/fd.h"
#include "storage/ipc.h"
#include "storage/lmgr.h"
#include "storage/procarray.h"
#include "storage/procsignal.h"
#include "storage/proc.h"
#include "storage/sinvaladt.h"
#include "storage/smgr.h"
#include "tcop/tcopprot.h"
#include "utils/acl.h"
#include "utils/fmgroids.h"
#include "utils/guc.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 "utils/tqual.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)
 
static void InitCommunication (void)
 
static void ShutdownPostgres (int code, Datum arg)
 
static void StatementTimeoutHandler (void)
 
static void LockTimeoutHandler (void)
 
static void IdleInTransactionSessionTimeoutHandler (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 BaseInit (void)
 
void InitPostgres (const char *in_dbname, Oid dboid, const char *username, Oid useroid, char *out_dbname)
 

Function Documentation

void BaseInit ( void  )

Definition at line 517 of file postinit.c.

References DebugFileOpen(), InitBufferPoolAccess(), InitCommunication(), InitFileAccess(), and smgrinit().

Referenced by AutoVacLauncherMain(), AutoVacWorkerMain(), AuxiliaryProcessMain(), PostgresMain(), and StartBackgroundWorker().

518 {
519  /*
520  * Attach to shared memory and semaphores, and initialize our
521  * input/output/debugging file descriptors.
522  */
524  DebugFileOpen();
525 
526  /* Do local initialization of file, storage and buffer managers */
527  InitFileAccess();
528  smgrinit();
530 }
static void InitCommunication(void)
Definition: postinit.c:409
void InitBufferPoolAccess(void)
Definition: bufmgr.c:2420
void DebugFileOpen(void)
Definition: elog.c:1863
void smgrinit(void)
Definition: smgr.c:102
void InitFileAccess(void)
Definition: fd.c:720
static void CheckMyDatabase ( const char *  name,
bool  am_superuser 
)
static

Definition at line 286 of file postinit.c.

References ACL_CONNECT, ACLCHECK_OK, check_strxfrm_bug(), CountDBConnections(), DATABASEOID, elog, ereport, errcode(), errdetail(), errhint(), errmsg(), ERROR, FATAL, GetDatabaseEncodingName(), GETSTRUCT, GetUserId(), HeapTupleIsValid, IsAutoVacuumWorkerProcess(), IsUnderPostmaster, MyDatabaseId, NameStr, NULL, ObjectIdGetDatum, pg_database_aclcheck(), pg_perm_setlocale(), PGC_BACKEND, PGC_INTERNAL, PGC_S_DYNAMIC_DEFAULT, PGC_S_OVERRIDE, ReleaseSysCache(), SearchSysCache1, SetConfigOption(), and SetDatabaseEncoding().

Referenced by InitPostgres().

287 {
288  HeapTuple tup;
289  Form_pg_database dbform;
290  char *collate;
291  char *ctype;
292 
293  /* Fetch our pg_database row normally, via syscache */
295  if (!HeapTupleIsValid(tup))
296  elog(ERROR, "cache lookup failed for database %u", MyDatabaseId);
297  dbform = (Form_pg_database) GETSTRUCT(tup);
298 
299  /* This recheck is strictly paranoia */
300  if (strcmp(name, NameStr(dbform->datname)) != 0)
301  ereport(FATAL,
302  (errcode(ERRCODE_UNDEFINED_DATABASE),
303  errmsg("database \"%s\" has disappeared from pg_database",
304  name),
305  errdetail("Database OID %u now seems to belong to \"%s\".",
306  MyDatabaseId, NameStr(dbform->datname))));
307 
308  /*
309  * Check permissions to connect to the database.
310  *
311  * These checks are not enforced when in standalone mode, so that there is
312  * a way to recover from disabling all access to all databases, for
313  * example "UPDATE pg_database SET datallowconn = false;".
314  *
315  * We do not enforce them for autovacuum worker processes either.
316  */
318  {
319  /*
320  * Check that the database is currently allowing connections.
321  */
322  if (!dbform->datallowconn)
323  ereport(FATAL,
324  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
325  errmsg("database \"%s\" is not currently accepting connections",
326  name)));
327 
328  /*
329  * Check privilege to connect to the database. (The am_superuser test
330  * is redundant, but since we have the flag, might as well check it
331  * and save a few cycles.)
332  */
333  if (!am_superuser &&
336  ereport(FATAL,
337  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
338  errmsg("permission denied for database \"%s\"", name),
339  errdetail("User does not have CONNECT privilege.")));
340 
341  /*
342  * Check connection limit for this database.
343  *
344  * There is a race condition here --- we create our PGPROC before
345  * checking for other PGPROCs. If two backends did this at about the
346  * same time, they might both think they were over the limit, while
347  * ideally one should succeed and one fail. Getting that to work
348  * exactly seems more trouble than it is worth, however; instead we
349  * just document that the connection limit is approximate.
350  */
351  if (dbform->datconnlimit >= 0 &&
352  !am_superuser &&
353  CountDBConnections(MyDatabaseId) > dbform->datconnlimit)
354  ereport(FATAL,
355  (errcode(ERRCODE_TOO_MANY_CONNECTIONS),
356  errmsg("too many connections for database \"%s\"",
357  name)));
358  }
359 
360  /*
361  * OK, we're golden. Next to-do item is to save the encoding info out of
362  * the pg_database tuple.
363  */
364  SetDatabaseEncoding(dbform->encoding);
365  /* Record it as a GUC internal option, too */
366  SetConfigOption("server_encoding", GetDatabaseEncodingName(),
368  /* If we have no other source of client_encoding, use server encoding */
369  SetConfigOption("client_encoding", GetDatabaseEncodingName(),
371 
372  /* assign locale variables */
373  collate = NameStr(dbform->datcollate);
374  ctype = NameStr(dbform->datctype);
375 
376  if (pg_perm_setlocale(LC_COLLATE, collate) == NULL)
377  ereport(FATAL,
378  (errmsg("database locale is incompatible with operating system"),
379  errdetail("The database was initialized with LC_COLLATE \"%s\", "
380  " which is not recognized by setlocale().", collate),
381  errhint("Recreate the database with another locale or install the missing locale.")));
382 
383  if (pg_perm_setlocale(LC_CTYPE, ctype) == NULL)
384  ereport(FATAL,
385  (errmsg("database locale is incompatible with operating system"),
386  errdetail("The database was initialized with LC_CTYPE \"%s\", "
387  " which is not recognized by setlocale().", ctype),
388  errhint("Recreate the database with another locale or install the missing locale.")));
389 
390  /* Make the locale settings visible as GUC variables, too */
391  SetConfigOption("lc_collate", collate, PGC_INTERNAL, PGC_S_OVERRIDE);
392  SetConfigOption("lc_ctype", ctype, PGC_INTERNAL, PGC_S_OVERRIDE);
393 
395 
396  ReleaseSysCache(tup);
397 }
int errhint(const char *fmt,...)
Definition: elog.c:987
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
Oid GetUserId(void)
Definition: miscinit.c:283
FormData_pg_database * Form_pg_database
Definition: pg_database.h:57
int errcode(int sqlerrcode)
Definition: elog.c:575
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
char * pg_perm_setlocale(int category, const char *locale)
Definition: pg_locale.c:146
int CountDBConnections(Oid databaseid)
Definition: procarray.c:2752
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
#define FATAL
Definition: elog.h:52
void check_strxfrm_bug(void)
Definition: pg_locale.c:988
void SetConfigOption(const char *name, const char *value, GucContext context, GucSource source)
Definition: guc.c:6633
bool IsUnderPostmaster
Definition: globals.c:100
int errdetail(const char *fmt,...)
Definition: elog.c:873
bool IsAutoVacuumWorkerProcess(void)
Definition: autovacuum.c:2989
#define ereport(elevel, rest)
Definition: elog.h:122
#define ACL_CONNECT
Definition: parsenodes.h:77
void SetDatabaseEncoding(int encoding)
Definition: mbutils.c:909
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
Oid MyDatabaseId
Definition: globals.c:76
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
AclResult pg_database_aclcheck(Oid db_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4409
#define NULL
Definition: c.h:226
const char * GetDatabaseEncodingName(void)
Definition: mbutils.c:1021
const char * name
Definition: encode.c:521
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define NameStr(name)
Definition: c.h:494
#define elog
Definition: elog.h:219
static HeapTuple GetDatabaseTuple ( const char *  dbname)
static

Definition at line 94 of file postinit.c.

References AccessShareLock, Anum_pg_database_datname, BTEqualStrategyNumber, criticalSharedRelcachesBuilt, CStringGetDatum, DatabaseNameIndexId, DatabaseRelationId, heap_close, heap_copytuple(), heap_open(), HeapTupleIsValid, NULL, ScanKeyInit(), systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by InitPostgres().

95 {
96  HeapTuple tuple;
97  Relation relation;
98  SysScanDesc scan;
99  ScanKeyData key[1];
100 
101  /*
102  * form a scan key
103  */
104  ScanKeyInit(&key[0],
106  BTEqualStrategyNumber, F_NAMEEQ,
108 
109  /*
110  * Open pg_database and fetch a tuple. Force heap scan if we haven't yet
111  * built the critical shared relcache entries (i.e., we're starting up
112  * without a shared relcache cache file).
113  */
115  scan = systable_beginscan(relation, DatabaseNameIndexId,
117  NULL,
118  1, key);
119 
120  tuple = systable_getnext(scan);
121 
122  /* Must copy tuple before releasing buffer */
123  if (HeapTupleIsValid(tuple))
124  tuple = heap_copytuple(tuple);
125 
126  /* all done */
127  systable_endscan(scan);
128  heap_close(relation, AccessShareLock);
129 
130  return tuple;
131 }
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:608
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:493
#define DatabaseRelationId
Definition: pg_database.h:29
#define AccessShareLock
Definition: lockdefs.h:36
bool criticalSharedRelcachesBuilt
Definition: relcache.c:134
#define heap_close(r, l)
Definition: heapam.h:97
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:322
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:410
#define Anum_pg_database_datname
Definition: pg_database.h:64
#define CStringGetDatum(X)
Definition: postgres.h:586
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:226
char * dbname
Definition: streamutil.c:41
#define DatabaseNameIndexId
Definition: indexing.h:140
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31
static HeapTuple GetDatabaseTupleByOid ( Oid  dboid)
static

Definition at line 137 of file postinit.c.

References AccessShareLock, BTEqualStrategyNumber, criticalSharedRelcachesBuilt, DatabaseOidIndexId, DatabaseRelationId, heap_close, heap_copytuple(), heap_open(), HeapTupleIsValid, NULL, ObjectIdAttributeNumber, ObjectIdGetDatum, ScanKeyInit(), systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by InitPostgres().

138 {
139  HeapTuple tuple;
140  Relation relation;
141  SysScanDesc scan;
142  ScanKeyData key[1];
143 
144  /*
145  * form a scan key
146  */
147  ScanKeyInit(&key[0],
149  BTEqualStrategyNumber, F_OIDEQ,
150  ObjectIdGetDatum(dboid));
151 
152  /*
153  * Open pg_database and fetch a tuple. Force heap scan if we haven't yet
154  * built the critical shared relcache entries (i.e., we're starting up
155  * without a shared relcache cache file).
156  */
158  scan = systable_beginscan(relation, DatabaseOidIndexId,
160  NULL,
161  1, key);
162 
163  tuple = systable_getnext(scan);
164 
165  /* Must copy tuple before releasing buffer */
166  if (HeapTupleIsValid(tuple))
167  tuple = heap_copytuple(tuple);
168 
169  /* all done */
170  systable_endscan(scan);
171  heap_close(relation, AccessShareLock);
172 
173  return tuple;
174 }
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:608
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:493
#define ObjectIdAttributeNumber
Definition: sysattr.h:22
#define DatabaseRelationId
Definition: pg_database.h:29
#define AccessShareLock
Definition: lockdefs.h:36
bool criticalSharedRelcachesBuilt
Definition: relcache.c:134
#define heap_close(r, l)
Definition: heapam.h:97
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:322
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:410
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define DatabaseOidIndexId
Definition: indexing.h:142
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:226
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31
static void IdleInTransactionSessionTimeoutHandler ( void  )
static

Definition at line 1184 of file postinit.c.

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

Referenced by InitPostgres().

1185 {
1187  InterruptPending = true;
1188  SetLatch(MyLatch);
1189 }
volatile bool IdleInTransactionSessionTimeoutPending
Definition: globals.c:33
volatile bool InterruptPending
Definition: globals.c:29
void SetLatch(volatile Latch *latch)
Definition: latch.c:380
struct Latch * MyLatch
Definition: globals.c:51
static void InitCommunication ( void  )
static

Definition at line 409 of file postinit.c.

References CreateSharedMemoryAndSemaphores(), and IsUnderPostmaster.

Referenced by BaseInit().

410 {
411  /*
412  * initialize shared memory and semaphores appropriately.
413  */
414  if (!IsUnderPostmaster) /* postmaster already did this */
415  {
416  /*
417  * We're running a postgres bootstrap process or a standalone backend.
418  * Create private "shmem" and semaphores.
419  */
421  }
422 }
bool IsUnderPostmaster
Definition: globals.c:100
void CreateSharedMemoryAndSemaphores(bool makePrivate, int port)
Definition: ipci.c:96
void InitializeMaxBackends ( void  )

Definition at line 495 of file postinit.c.

References Assert, autovacuum_max_workers, elog, ERROR, MAX_BACKENDS, max_worker_processes, MaxBackends, and MaxConnections.

Referenced by AuxiliaryProcessMain(), PostgresMain(), and PostmasterMain().

496 {
497  Assert(MaxBackends == 0);
498 
499  /* the extra unit accounts for the autovacuum launcher */
502 
503  /* internal error because the values were all checked previously */
505  elog(ERROR, "too many backends configured");
506 }
#define ERROR
Definition: elog.h:43
#define MAX_BACKENDS
Definition: postmaster.h:75
int MaxBackends
Definition: globals.c:126
int MaxConnections
Definition: globals.c:123
int autovacuum_max_workers
Definition: autovacuum.c:112
#define Assert(condition)
Definition: c.h:670
int max_worker_processes
Definition: globals.c:124
#define elog
Definition: elog.h:219
void InitPostgres ( const char *  in_dbname,
Oid  dboid,
const char *  username,
Oid  useroid,
char *  out_dbname 
)

Definition at line 558 of file postinit.c.

References am_db_walsender, am_walsender, Assert, before_shmem_exit(), CAC_WAITBACKUP, Port::canAcceptConnections, CheckDeadLockAlert(), CheckMyDatabase(), CommitTransactionCommand(), PGPROC::databaseId, DatabaseRelationId, dbname, DEADLOCK_TIMEOUT, DEBUG3, DEFAULTTABLESPACE_OID, elog, EnablePortalManager(), ereport, errcode(), errcode_for_file_access(), errdetail(), errhint(), errmsg(), FATAL, GetDatabasePath(), GetDatabaseTuple(), GetDatabaseTupleByOid(), GetSessionUserId(), GETSTRUCT, GetTransactionSnapshot(), GetUserId(), has_rolreplication(), HaveNFreeProcs(), HeapTupleGetOid, HeapTupleIsValid, IDLE_IN_TRANSACTION_SESSION_TIMEOUT, IdleInTransactionSessionTimeoutHandler(), InitBufferPoolBackend(), InitCatalogCache(), initialize_acl(), InitializeClientEncoding(), InitializeSearchPath(), InitializeSessionUserId(), InitializeSessionUserIdStandalone(), InitPlanCache(), InitProcessPhase2(), InvalidateCatalogSnapshot(), InvalidBackendId, IsAutoVacuumLauncherProcess(), IsAutoVacuumWorkerProcess(), IsBackgroundWorker, IsBinaryUpgrade, IsBootstrapProcessingMode, IsUnderPostmaster, LOCK_TIMEOUT, LockSharedObject(), LockTimeoutHandler(), MaxBackends, MyBackendId, MyDatabaseId, MyDatabaseTableSpace, MyProc, MyProcPort, NAMEDATALEN, NameStr, NULL, OidIsValid, on_shmem_exit(), PerformAuthentication(), pg_usleep(), pgstat_bestart(), pgstat_initialize(), PostAuthDelay, process_settings(), process_startup_options(), ProcSignalInit(), RecoveryInProgress(), RegisterTimeout(), RelationCacheInitialize(), RelationCacheInitializePhase2(), RelationCacheInitializePhase3(), ReservedBackends, RowExclusiveLock, SetCurrentStatementStartTimestamp(), SetDatabasePath(), SharedInvalBackendInit(), ShutdownPostgres(), ShutdownXLOG(), StartTransactionCommand(), StartupXLOG(), STATEMENT_TIMEOUT, StatementTimeoutHandler(), strlcpy(), superuser(), TemplateDbOid, ThereIsAtLeastOneRole(), ValidatePgVersion(), WARNING, XACT_READ_COMMITTED, and XactIsoLevel.

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

560 {
561  bool bootstrap = IsBootstrapProcessingMode();
562  bool am_superuser;
563  char *fullpath;
564  char dbname[NAMEDATALEN];
565 
566  elog(DEBUG3, "InitPostgres");
567 
568  /*
569  * Add my PGPROC struct to the ProcArray.
570  *
571  * Once I have done this, I am visible to other backends!
572  */
574 
575  /*
576  * Initialize my entry in the shared-invalidation manager's array of
577  * per-backend data.
578  *
579  * Sets up MyBackendId, a unique backend identifier.
580  */
582 
583  SharedInvalBackendInit(false);
584 
585  if (MyBackendId > MaxBackends || MyBackendId <= 0)
586  elog(FATAL, "bad backend ID: %d", MyBackendId);
587 
588  /* Now that we have a BackendId, we can participate in ProcSignal */
590 
591  /*
592  * Also set up timeout handlers needed for backend operation. We need
593  * these in every case except bootstrap.
594  */
595  if (!bootstrap)
596  {
602  }
603 
604  /*
605  * bufmgr needs another initialization call too
606  */
608 
609  /*
610  * Initialize local process's access to XLOG.
611  */
612  if (IsUnderPostmaster)
613  {
614  /*
615  * The postmaster already started the XLOG machinery, but we need to
616  * call InitXLOGAccess(), if the system isn't in hot-standby mode.
617  * This is handled by calling RecoveryInProgress and ignoring the
618  * result.
619  */
620  (void) RecoveryInProgress();
621  }
622  else
623  {
624  /*
625  * We are either a bootstrap process or a standalone backend. Either
626  * way, start up the XLOG machinery, and register to have it closed
627  * down at exit.
628  */
629  StartupXLOG();
631  }
632 
633  /*
634  * Initialize the relation cache and the system catalog caches. Note that
635  * no catalog access happens here; we only set up the hashtable structure.
636  * We must do this before starting a transaction because transaction abort
637  * would try to touch these hashtables.
638  */
641  InitPlanCache();
642 
643  /* Initialize portal manager */
645 
646  /* Initialize stats collection --- must happen before first xact */
647  if (!bootstrap)
649 
650  /*
651  * Load relcache entries for the shared system catalogs. This must create
652  * at least entries for pg_database and catalogs used for authentication.
653  */
655 
656  /*
657  * Set up process-exit callback to do pre-shutdown cleanup. This is the
658  * first before_shmem_exit callback we register; thus, this will be the
659  * last thing we do before low-level modules like the buffer manager begin
660  * to close down. We need to have this in place before we begin our first
661  * transaction --- if we fail during the initialization transaction, as is
662  * entirely possible, we need the AbortTransaction call to clean up.
663  */
665 
666  /* The autovacuum launcher is done here */
668  return;
669 
670  /*
671  * Start a new transaction here before first access to db, and get a
672  * snapshot. We don't have a use for the snapshot itself, but we're
673  * interested in the secondary effect that it sets RecentGlobalXmin. (This
674  * is critical for anything that reads heap pages, because HOT may decide
675  * to prune them even if the process doesn't attempt to modify any
676  * tuples.)
677  */
678  if (!bootstrap)
679  {
680  /* statement_timestamp must be set for timeouts to work correctly */
683 
684  /*
685  * transaction_isolation will have been set to the default by the
686  * above. If the default is "serializable", and we are in hot
687  * standby, we will fail if we don't change it to something lower.
688  * Fortunately, "read committed" is plenty good enough.
689  */
691 
692  (void) GetTransactionSnapshot();
693  }
694 
695  /*
696  * Perform client authentication if necessary, then figure out our
697  * postgres user ID, and see if we are a superuser.
698  *
699  * In standalone mode and in autovacuum worker processes, we use a fixed
700  * ID, otherwise we figure it out from the authenticated user name.
701  */
702  if (bootstrap || IsAutoVacuumWorkerProcess())
703  {
705  am_superuser = true;
706  }
707  else if (!IsUnderPostmaster)
708  {
710  am_superuser = true;
711  if (!ThereIsAtLeastOneRole())
713  (errcode(ERRCODE_UNDEFINED_OBJECT),
714  errmsg("no roles are defined in this database system"),
715  errhint("You should immediately run CREATE USER \"%s\" SUPERUSER;.",
716  username != NULL ? username : "postgres")));
717  }
718  else if (IsBackgroundWorker)
719  {
720  if (username == NULL && !OidIsValid(useroid))
721  {
723  am_superuser = true;
724  }
725  else
726  {
728  am_superuser = superuser();
729  }
730  }
731  else
732  {
733  /* normal multiuser case */
734  Assert(MyProcPort != NULL);
737  am_superuser = superuser();
738  }
739 
740  /*
741  * If we're trying to shut down, only superusers can connect, and new
742  * replication connections are not allowed.
743  */
744  if ((!am_superuser || am_walsender) &&
745  MyProcPort != NULL &&
747  {
748  if (am_walsender)
749  ereport(FATAL,
750  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
751  errmsg("new replication connections are not allowed during database shutdown")));
752  else
753  ereport(FATAL,
754  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
755  errmsg("must be superuser to connect during database shutdown")));
756  }
757 
758  /*
759  * Binary upgrades only allowed super-user connections
760  */
761  if (IsBinaryUpgrade && !am_superuser)
762  {
763  ereport(FATAL,
764  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
765  errmsg("must be superuser to connect in binary upgrade mode")));
766  }
767 
768  /*
769  * The last few connections slots are reserved for superusers. Although
770  * replication connections currently require superuser privileges, we
771  * don't allow them to consume the reserved slots, which are intended for
772  * interactive use.
773  */
774  if ((!am_superuser || am_walsender) &&
775  ReservedBackends > 0 &&
777  ereport(FATAL,
778  (errcode(ERRCODE_TOO_MANY_CONNECTIONS),
779  errmsg("remaining connection slots are reserved for non-replication superuser connections")));
780 
781  /* Check replication permissions needed for walsender processes. */
782  if (am_walsender)
783  {
784  Assert(!bootstrap);
785 
786  if (!superuser() && !has_rolreplication(GetUserId()))
787  ereport(FATAL,
788  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
789  errmsg("must be superuser or replication role to start walsender")));
790  }
791 
792  /*
793  * If this is a plain walsender only supporting physical replication, we
794  * don't want to connect to any particular database. Just finish the
795  * backend startup by processing any options from the startup packet, and
796  * we're done.
797  */
799  {
800  /* process any options passed in the startup packet */
801  if (MyProcPort != NULL)
802  process_startup_options(MyProcPort, am_superuser);
803 
804  /* Apply PostAuthDelay as soon as we've read all options */
805  if (PostAuthDelay > 0)
806  pg_usleep(PostAuthDelay * 1000000L);
807 
808  /* initialize client encoding */
810 
811  /* report this backend in the PgBackendStatus array */
812  pgstat_bestart();
813 
814  /* close the transaction we started above */
816 
817  return;
818  }
819 
820  /*
821  * Set up the global variables holding database id and default tablespace.
822  * But note we won't actually try to touch the database just yet.
823  *
824  * We take a shortcut in the bootstrap case, otherwise we have to look up
825  * the db's entry in pg_database.
826  */
827  if (bootstrap)
828  {
831  }
832  else if (in_dbname != NULL)
833  {
834  HeapTuple tuple;
835  Form_pg_database dbform;
836 
837  tuple = GetDatabaseTuple(in_dbname);
838  if (!HeapTupleIsValid(tuple))
839  ereport(FATAL,
840  (errcode(ERRCODE_UNDEFINED_DATABASE),
841  errmsg("database \"%s\" does not exist", in_dbname)));
842  dbform = (Form_pg_database) GETSTRUCT(tuple);
843  MyDatabaseId = HeapTupleGetOid(tuple);
844  MyDatabaseTableSpace = dbform->dattablespace;
845  /* take database name from the caller, just for paranoia */
846  strlcpy(dbname, in_dbname, sizeof(dbname));
847  }
848  else if (OidIsValid(dboid))
849  {
850  /* caller specified database by OID */
851  HeapTuple tuple;
852  Form_pg_database dbform;
853 
854  tuple = GetDatabaseTupleByOid(dboid);
855  if (!HeapTupleIsValid(tuple))
856  ereport(FATAL,
857  (errcode(ERRCODE_UNDEFINED_DATABASE),
858  errmsg("database %u does not exist", dboid)));
859  dbform = (Form_pg_database) GETSTRUCT(tuple);
860  MyDatabaseId = HeapTupleGetOid(tuple);
861  MyDatabaseTableSpace = dbform->dattablespace;
862  Assert(MyDatabaseId == dboid);
863  strlcpy(dbname, NameStr(dbform->datname), sizeof(dbname));
864  /* pass the database name back to the caller */
865  if (out_dbname)
866  strcpy(out_dbname, dbname);
867  }
868  else
869  {
870  /*
871  * If this is a background worker not bound to any particular
872  * database, we're done now. Everything that follows only makes sense
873  * if we are bound to a specific database. We do need to close the
874  * transaction we started before returning.
875  */
876  if (!bootstrap)
878  return;
879  }
880 
881  /*
882  * Now, take a writer's lock on the database we are trying to connect to.
883  * If there is a concurrently running DROP DATABASE on that database, this
884  * will block us until it finishes (and has committed its update of
885  * pg_database).
886  *
887  * Note that the lock is not held long, only until the end of this startup
888  * transaction. This is OK since we will advertise our use of the
889  * database in the ProcArray before dropping the lock (in fact, that's the
890  * next thing to do). Anyone trying a DROP DATABASE after this point will
891  * see us in the array once they have the lock. Ordering is important for
892  * this because we don't want to advertise ourselves as being in this
893  * database until we have the lock; otherwise we create what amounts to a
894  * deadlock with CountOtherDBBackends().
895  *
896  * Note: use of RowExclusiveLock here is reasonable because we envision
897  * our session as being a concurrent writer of the database. If we had a
898  * way of declaring a session as being guaranteed-read-only, we could use
899  * AccessShareLock for such sessions and thereby not conflict against
900  * CREATE DATABASE.
901  */
902  if (!bootstrap)
905 
906  /*
907  * Now we can mark our PGPROC entry with the database ID.
908  *
909  * We assume this is an atomic store so no lock is needed; though actually
910  * things would work fine even if it weren't atomic. Anyone searching the
911  * ProcArray for this database's ID should hold the database lock, so they
912  * would not be executing concurrently with this store. A process looking
913  * for another database's ID could in theory see a chance match if it read
914  * a partially-updated databaseId value; but as long as all such searches
915  * wait and retry, as in CountOtherDBBackends(), they will certainly see
916  * the correct value on their next try.
917  */
919 
920  /*
921  * We established a catalog snapshot while reading pg_authid and/or
922  * pg_database; but until we have set up MyDatabaseId, we won't react to
923  * incoming sinval messages for unshared catalogs, so we won't realize it
924  * if the snapshot has been invalidated. Assume it's no good anymore.
925  */
927 
928  /*
929  * Recheck pg_database to make sure the target database hasn't gone away.
930  * If there was a concurrent DROP DATABASE, this ensures we will die
931  * cleanly without creating a mess.
932  */
933  if (!bootstrap)
934  {
935  HeapTuple tuple;
936 
937  tuple = GetDatabaseTuple(dbname);
938  if (!HeapTupleIsValid(tuple) ||
939  MyDatabaseId != HeapTupleGetOid(tuple) ||
940  MyDatabaseTableSpace != ((Form_pg_database) GETSTRUCT(tuple))->dattablespace)
941  ereport(FATAL,
942  (errcode(ERRCODE_UNDEFINED_DATABASE),
943  errmsg("database \"%s\" does not exist", dbname),
944  errdetail("It seems to have just been dropped or renamed.")));
945  }
946 
947  /*
948  * Now we should be able to access the database directory safely. Verify
949  * it's there and looks reasonable.
950  */
952 
953  if (!bootstrap)
954  {
955  if (access(fullpath, F_OK) == -1)
956  {
957  if (errno == ENOENT)
958  ereport(FATAL,
959  (errcode(ERRCODE_UNDEFINED_DATABASE),
960  errmsg("database \"%s\" does not exist",
961  dbname),
962  errdetail("The database subdirectory \"%s\" is missing.",
963  fullpath)));
964  else
965  ereport(FATAL,
967  errmsg("could not access directory \"%s\": %m",
968  fullpath)));
969  }
970 
971  ValidatePgVersion(fullpath);
972  }
973 
974  SetDatabasePath(fullpath);
975 
976  /*
977  * It's now possible to do real access to the system catalogs.
978  *
979  * Load relcache entries for the system catalogs. This must create at
980  * least the minimum set of "nailed-in" cache entries.
981  */
983 
984  /* set up ACL framework (so CheckMyDatabase can check permissions) */
985  initialize_acl();
986 
987  /*
988  * Re-read the pg_database row for our database, check permissions and set
989  * up database-specific GUC settings. We can't do this until all the
990  * database-access infrastructure is up. (Also, it wants to know if the
991  * user is a superuser, so the above stuff has to happen first.)
992  */
993  if (!bootstrap)
994  CheckMyDatabase(dbname, am_superuser);
995 
996  /*
997  * Now process any command-line switches and any additional GUC variable
998  * settings passed in the startup packet. We couldn't do this before
999  * because we didn't know if client is a superuser.
1000  */
1001  if (MyProcPort != NULL)
1002  process_startup_options(MyProcPort, am_superuser);
1003 
1004  /* Process pg_db_role_setting options */
1006 
1007  /* Apply PostAuthDelay as soon as we've read all options */
1008  if (PostAuthDelay > 0)
1009  pg_usleep(PostAuthDelay * 1000000L);
1010 
1011  /*
1012  * Initialize various default states that can't be set up until we've
1013  * selected the active user and gotten the right GUC settings.
1014  */
1015 
1016  /* set default namespace search path */
1018 
1019  /* initialize client encoding */
1021 
1022  /* report this backend in the PgBackendStatus array */
1023  if (!bootstrap)
1024  pgstat_bestart();
1025 
1026  /* close the transaction we started above */
1027  if (!bootstrap)
1029 }
int errhint(const char *fmt,...)
Definition: elog.c:987
BackendId MyBackendId
Definition: globals.c:72
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
struct Port * MyProcPort
Definition: globals.c:40
CAC_state canAcceptConnections
Definition: libpq-be.h:131
void SharedInvalBackendInit(bool sendOnly)
Definition: sinvaladt.c:258
#define DEBUG3
Definition: elog.h:23
Oid GetUserId(void)
Definition: miscinit.c:283
FormData_pg_database * Form_pg_database
Definition: pg_database.h:57
PGPROC * MyProc
Definition: proc.c:67
static HeapTuple GetDatabaseTuple(const char *dbname)
Definition: postinit.c:94
#define DatabaseRelationId
Definition: pg_database.h:29
void CommitTransactionCommand(void)
Definition: xact.c:2745
void ValidatePgVersion(const char *path)
Definition: miscinit.c:1333
void RelationCacheInitializePhase2(void)
Definition: relcache.c:3563
static void PerformAuthentication(Port *port)
Definition: postinit.c:183
static void LockTimeoutHandler(void)
Definition: postinit.c:1174
int errcode(int sqlerrcode)
Definition: elog.c:575
bool superuser(void)
Definition: superuser.c:47
static void CheckMyDatabase(const char *name, bool am_superuser)
Definition: postinit.c:286
void initialize_acl(void)
Definition: acl.c:4612
bool RecoveryInProgress(void)
Definition: xlog.c:7825
Snapshot GetTransactionSnapshot(void)
Definition: snapmgr.c:300
#define OidIsValid(objectId)
Definition: c.h:533
Oid GetSessionUserId(void)
Definition: miscinit.c:317
bool HaveNFreeProcs(int n)
Definition: proc.c:637
bool IsBinaryUpgrade
Definition: globals.c:101
Oid MyDatabaseTableSpace
Definition: globals.c:78
bool IsBackgroundWorker
Definition: globals.c:102
void RelationCacheInitializePhase3(void)
Definition: relcache.c:3622
#define NAMEDATALEN
bool am_walsender
Definition: walsender.c:106
void pg_usleep(long microsec)
Definition: signal.c:53
int ReservedBackends
Definition: postmaster.c:211
#define FATAL
Definition: elog.h:52
void InitializeSearchPath(void)
Definition: namespace.c:3960
int MaxBackends
Definition: globals.c:126
#define TemplateDbOid
Definition: pg_database.h:80
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:348
bool IsUnderPostmaster
Definition: globals.c:100
#define RowExclusiveLock
Definition: lockdefs.h:38
#define DEFAULTTABLESPACE_OID
Definition: pg_tablespace.h:63
int errdetail(const char *fmt,...)
Definition: elog.c:873
int errcode_for_file_access(void)
Definition: elog.c:598
static void IdleInTransactionSessionTimeoutHandler(void)
Definition: postinit.c:1184
void before_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:320
Oid databaseId
Definition: proc.h:103
void pgstat_initialize(void)
Definition: pgstat.c:2642
static bool ThereIsAtLeastOneRole(void)
Definition: postinit.c:1195
void StartupXLOG(void)
Definition: xlog.c:6152
bool IsAutoVacuumWorkerProcess(void)
Definition: autovacuum.c:2989
#define ereport(elevel, rest)
Definition: elog.h:122
void InvalidateCatalogSnapshot(void)
Definition: snapmgr.c:506
char * GetDatabasePath(Oid dbNode, Oid spcNode)
Definition: relpath.c:108
void SetDatabasePath(const char *path)
Definition: miscinit.c:82
#define WARNING
Definition: elog.h:40
void ShutdownXLOG(int code, Datum arg)
Definition: xlog.c:8273
static HeapTuple GetDatabaseTupleByOid(Oid dboid)
Definition: postinit.c:137
#define InvalidBackendId
Definition: backendid.h:23
bool am_db_walsender
Definition: walsender.c:109
Oid MyDatabaseId
Definition: globals.c:76
int PostAuthDelay
Definition: postgres.c:97
void LockSharedObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:871
void EnablePortalManager(void)
Definition: portalmem.c:103
static void ShutdownPostgres(int code, Datum arg)
Definition: postinit.c:1135
static char * username
Definition: initdb.c:130
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
TimeoutId RegisterTimeout(TimeoutId id, timeout_handler_proc handler)
Definition: timeout.c:373
bool IsAutoVacuumLauncherProcess(void)
Definition: autovacuum.c:2983
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:670
void InitializeSessionUserIdStandalone(void)
Definition: miscinit.c:578
void StartTransactionCommand(void)
Definition: xact.c:2675
#define XACT_READ_COMMITTED
Definition: xact.h:29
void InitializeSessionUserId(const char *rolename, Oid roleid)
Definition: miscinit.c:482
char * dbname
Definition: streamutil.c:41
static void process_startup_options(Port *port, bool am_superuser)
Definition: postinit.c:1036
int XactIsoLevel
Definition: xact.c:74
bool has_rolreplication(Oid roleid)
Definition: miscinit.c:464
void InitializeClientEncoding(void)
Definition: mbutils.c:293
void InitPlanCache(void)
Definition: plancache.c:115
void InitProcessPhase2(void)
Definition: proc.c:447
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:365
void RelationCacheInitialize(void)
Definition: relcache.c:3526
void ProcSignalInit(int pss_idx)
Definition: procsignal.c:104
void InitCatalogCache(void)
Definition: syscache.c:967
static void StatementTimeoutHandler(void)
Definition: postinit.c:1152
void SetCurrentStatementStartTimestamp(void)
Definition: xact.c:739
int errmsg(const char *fmt,...)
Definition: elog.c:797
void pgstat_bestart(void)
Definition: pgstat.c:2662
#define NameStr(name)
Definition: c.h:494
static void process_settings(Oid databaseid, Oid roleid)
Definition: postinit.c:1101
void CheckDeadLockAlert(void)
Definition: proc.c:1716
void InitBufferPoolBackend(void)
Definition: bufmgr.c:2444
#define elog
Definition: elog.h:219
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
static void LockTimeoutHandler ( void  )
static

Definition at line 1174 of file postinit.c.

References MyProcPid.

Referenced by InitPostgres().

1175 {
1176 #ifdef HAVE_SETSID
1177  /* try to signal whole process group */
1178  kill(-MyProcPid, SIGINT);
1179 #endif
1180  kill(MyProcPid, SIGINT);
1181 }
int MyProcPid
Definition: globals.c:38
static void PerformAuthentication ( Port port)
static

Definition at line 183 of file postinit.c.

References _, ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate(), am_walsender, AuthenticationTimeout, ClientAuthentication(), ClientAuthInProgress, Port::database_name, disable_timeout(), enable_timeout_after(), ereport, errmsg(), FATAL, load_hba(), load_ident(), LOG, Log_connections, NULL, PostmasterContext, set_ps_display(), SSL_get_current_compression, Port::ssl_in_use, STATEMENT_TIMEOUT, TopMemoryContext, and Port::user_name.

Referenced by InitPostgres().

184 {
185  /* This should be set already, but let's make sure */
186  ClientAuthInProgress = true; /* limit visibility of log messages */
187 
188  /*
189  * In EXEC_BACKEND case, we didn't inherit the contents of pg_hba.conf
190  * etcetera from the postmaster, and have to load them ourselves.
191  *
192  * FIXME: [fork/exec] Ugh. Is there a way around this overhead?
193  */
194 #ifdef EXEC_BACKEND
195 
196  /*
197  * load_hba() and load_ident() want to work within the PostmasterContext,
198  * so create that if it doesn't exist (which it won't). We'll delete it
199  * again later, in PostgresMain.
200  */
201  if (PostmasterContext == NULL)
203  "Postmaster",
205 
206  if (!load_hba())
207  {
208  /*
209  * It makes no sense to continue if we fail to load the HBA file,
210  * since there is no way to connect to the database in this case.
211  */
212  ereport(FATAL,
213  (errmsg("could not load pg_hba.conf")));
214  }
215 
216  if (!load_ident())
217  {
218  /*
219  * It is ok to continue if we fail to load the IDENT file, although it
220  * means that you cannot log in using any of the authentication
221  * methods that need a user name mapping. load_ident() already logged
222  * the details of error to the log.
223  */
224  }
225 #endif
226 
227  /*
228  * Set up a timeout in case a buggy or malicious client fails to respond
229  * during authentication. Since we're inside a transaction and might do
230  * database access, we have to use the statement_timeout infrastructure.
231  */
233 
234  /*
235  * Now perform authentication exchange.
236  */
237  ClientAuthentication(port); /* might not return, if failure */
238 
239  /*
240  * Done with authentication. Disable the timeout, and log if needed.
241  */
243 
244  if (Log_connections)
245  {
246  if (am_walsender)
247  {
248 #ifdef USE_OPENSSL
249  if (port->ssl_in_use)
250  ereport(LOG,
251  (errmsg("replication connection authorized: user=%s SSL enabled (protocol=%s, cipher=%s, compression=%s)",
252  port->user_name, SSL_get_version(port->ssl), SSL_get_cipher(port->ssl),
253  SSL_get_current_compression(port->ssl) ? _("on") : _("off"))));
254  else
255 #endif
256  ereport(LOG,
257  (errmsg("replication connection authorized: user=%s",
258  port->user_name)));
259  }
260  else
261  {
262 #ifdef USE_OPENSSL
263  if (port->ssl_in_use)
264  ereport(LOG,
265  (errmsg("connection authorized: user=%s database=%s SSL enabled (protocol=%s, cipher=%s, compression=%s)",
266  port->user_name, port->database_name, SSL_get_version(port->ssl), SSL_get_cipher(port->ssl),
267  SSL_get_current_compression(port->ssl) ? _("on") : _("off"))));
268  else
269 #endif
270  ereport(LOG,
271  (errmsg("connection authorized: user=%s database=%s",
272  port->user_name, port->database_name)));
273  }
274  }
275 
276  set_ps_display("startup", false);
277 
278  ClientAuthInProgress = false; /* client_min_messages is active now */
279 }
void ClientAuthentication(Port *port)
Definition: auth.c:329
void set_ps_display(const char *activity, bool force)
Definition: ps_status.c:326
bool ssl_in_use
Definition: libpq-be.h:183
#define LOG
Definition: elog.h:26
bool Log_connections
Definition: postmaster.c:239
bool load_ident(void)
Definition: hba.c:2727
int AuthenticationTimeout
Definition: postmaster.c:236
bool ClientAuthInProgress
Definition: postmaster.c:348
bool am_walsender
Definition: walsender.c:106
#define FATAL
Definition: elog.h:52
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:145
bool load_hba(void)
Definition: hba.c:1945
char * user_name
Definition: libpq-be.h:139
#define ereport(elevel, rest)
Definition: elog.h:122
MemoryContext TopMemoryContext
Definition: mcxt.c:43
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: aset.c:440
#define SSL_get_current_compression(x)
Definition: port.h:419
void enable_timeout_after(TimeoutId id, int delay_ms)
Definition: timeout.c:428
#define NULL
Definition: c.h:226
int errmsg(const char *fmt,...)
Definition: elog.c:797
void disable_timeout(TimeoutId id, bool keep_indicator)
Definition: timeout.c:525
char * database_name
Definition: libpq-be.h:138
#define _(x)
Definition: elog.c:84
MemoryContext PostmasterContext
Definition: mcxt.c:45
void pg_split_opts ( char **  argv,
int *  argcp,
const char *  optstr 
)

Definition at line 436 of file postinit.c.

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

Referenced by BackendRun(), and process_startup_options().

437 {
438  StringInfoData s;
439 
440  initStringInfo(&s);
441 
442  while (*optstr)
443  {
444  bool last_was_escape = false;
445 
446  resetStringInfo(&s);
447 
448  /* skip over leading space */
449  while (isspace((unsigned char) *optstr))
450  optstr++;
451 
452  if (*optstr == '\0')
453  break;
454 
455  /*
456  * Parse a single option, stopping at the first space, unless it's
457  * escaped.
458  */
459  while (*optstr)
460  {
461  if (isspace((unsigned char) *optstr) && !last_was_escape)
462  break;
463 
464  if (!last_was_escape && *optstr == '\\')
465  last_was_escape = true;
466  else
467  {
468  last_was_escape = false;
469  appendStringInfoChar(&s, *optstr);
470  }
471 
472  optstr++;
473  }
474 
475  /* now store the option in the next argv[] position */
476  argv[(*argcp)++] = pstrdup(s.data);
477  }
478 
479  pfree(s.data);
480 }
char * pstrdup(const char *in)
Definition: mcxt.c:1165
void pfree(void *pointer)
Definition: mcxt.c:992
void resetStringInfo(StringInfo str)
Definition: stringinfo.c:94
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:201
void initStringInfo(StringInfo str)
Definition: stringinfo.c:65
static void process_settings ( Oid  databaseid,
Oid  roleid 
)
static

Definition at line 1101 of file postinit.c.

References AccessShareLock, ApplySetting(), DbRoleSettingRelationId, GetCatalogSnapshot(), heap_close, heap_open(), InvalidOid, IsUnderPostmaster, PGC_S_DATABASE, PGC_S_DATABASE_USER, PGC_S_GLOBAL, PGC_S_USER, RegisterSnapshot(), and UnregisterSnapshot().

Referenced by InitPostgres().

1102 {
1103  Relation relsetting;
1104  Snapshot snapshot;
1105 
1106  if (!IsUnderPostmaster)
1107  return;
1108 
1110 
1111  /* read all the settings under the same snapshot for efficiency */
1113 
1114  /* Later settings are ignored if set earlier. */
1115  ApplySetting(snapshot, databaseid, roleid, relsetting, PGC_S_DATABASE_USER);
1116  ApplySetting(snapshot, InvalidOid, roleid, relsetting, PGC_S_USER);
1117  ApplySetting(snapshot, databaseid, InvalidOid, relsetting, PGC_S_DATABASE);
1118  ApplySetting(snapshot, InvalidOid, InvalidOid, relsetting, PGC_S_GLOBAL);
1119 
1120  UnregisterSnapshot(snapshot);
1121  heap_close(relsetting, AccessShareLock);
1122 }
Snapshot RegisterSnapshot(Snapshot snapshot)
Definition: snapmgr.c:858
Snapshot GetCatalogSnapshot(Oid relid)
Definition: snapmgr.c:436
#define AccessShareLock
Definition: lockdefs.h:36
#define heap_close(r, l)
Definition: heapam.h:97
bool IsUnderPostmaster
Definition: globals.c:100
void UnregisterSnapshot(Snapshot snapshot)
Definition: snapmgr.c:900
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define InvalidOid
Definition: postgres_ext.h:36
void ApplySetting(Snapshot snapshot, Oid databaseid, Oid roleid, Relation relsetting, GucSource source)
#define DbRoleSettingRelationId
static void process_startup_options ( Port port,
bool  am_superuser 
)
static

Definition at line 1036 of file postinit.c.

References Assert, av, Port::cmdline_options, Port::guc_options, lfirst, list_head(), lnext, name, NULL, palloc(), pg_split_opts(), PGC_BACKEND, PGC_S_CLIENT, PGC_SU_BACKEND, process_postgres_switches(), SetConfigOption(), and value.

Referenced by InitPostgres().

1037 {
1038  GucContext gucctx;
1039  ListCell *gucopts;
1040 
1041  gucctx = am_superuser ? PGC_SU_BACKEND : PGC_BACKEND;
1042 
1043  /*
1044  * First process any command-line switches that were included in the
1045  * startup packet, if we are in a regular backend.
1046  */
1047  if (port->cmdline_options != NULL)
1048  {
1049  /*
1050  * The maximum possible number of commandline arguments that could
1051  * come from port->cmdline_options is (strlen + 1) / 2; see
1052  * pg_split_opts().
1053  */
1054  char **av;
1055  int maxac;
1056  int ac;
1057 
1058  maxac = 2 + (strlen(port->cmdline_options) + 1) / 2;
1059 
1060  av = (char **) palloc(maxac * sizeof(char *));
1061  ac = 0;
1062 
1063  av[ac++] = "postgres";
1064 
1065  pg_split_opts(av, &ac, port->cmdline_options);
1066 
1067  av[ac] = NULL;
1068 
1069  Assert(ac < maxac);
1070 
1071  (void) process_postgres_switches(ac, av, gucctx, NULL);
1072  }
1073 
1074  /*
1075  * Process any additional GUC variable settings passed in startup packet.
1076  * These are handled exactly like command-line variables.
1077  */
1078  gucopts = list_head(port->guc_options);
1079  while (gucopts)
1080  {
1081  char *name;
1082  char *value;
1083 
1084  name = lfirst(gucopts);
1085  gucopts = lnext(gucopts);
1086 
1087  value = lfirst(gucopts);
1088  gucopts = lnext(gucopts);
1089 
1090  SetConfigOption(name, value, gucctx, PGC_S_CLIENT);
1091  }
1092 }
GucContext
Definition: guc.h:68
static struct @76 value
List * guc_options
Definition: libpq-be.h:141
void SetConfigOption(const char *name, const char *value, GucContext context, GucSource source)
Definition: guc.c:6633
void pg_split_opts(char **argv, int *argcp, const char *optstr)
Definition: postinit.c:436
static ListCell * list_head(const List *l)
Definition: pg_list.h:77
#define lnext(lc)
Definition: pg_list.h:105
struct @18::@19 av[32]
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:670
#define lfirst(lc)
Definition: pg_list.h:106
const char * name
Definition: encode.c:521
void * palloc(Size size)
Definition: mcxt.c:891
char * cmdline_options
Definition: libpq-be.h:140
void process_postgres_switches(int argc, char *argv[], GucContext ctx, const char **dbname)
Definition: postgres.c:3302
static void ShutdownPostgres ( int  code,
Datum  arg 
)
static

Definition at line 1135 of file postinit.c.

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

Referenced by InitPostgres().

1136 {
1137  /* Make sure we've killed any active transaction */
1139 
1140  /*
1141  * User locks are not released by transaction end, so be sure to release
1142  * them explicitly.
1143  */
1145 }
void AbortOutOfAnyTransaction(void)
Definition: xact.c:4220
#define USER_LOCKMETHOD
Definition: lock.h:130
void LockReleaseAll(LOCKMETHODID lockmethodid, bool allLocks)
Definition: lock.c:2014
static void StatementTimeoutHandler ( void  )
static

Definition at line 1152 of file postinit.c.

References ClientAuthInProgress, MyProcPid, and sig.

Referenced by InitPostgres().

1153 {
1154  int sig = SIGINT;
1155 
1156  /*
1157  * During authentication the timeout is used to deal with
1158  * authentication_timeout - we want to quit in response to such timeouts.
1159  */
1161  sig = SIGTERM;
1162 
1163 #ifdef HAVE_SETSID
1164  /* try to signal whole process group */
1165  kill(-MyProcPid, sig);
1166 #endif
1167  kill(MyProcPid, sig);
1168 }
int MyProcPid
Definition: globals.c:38
bool ClientAuthInProgress
Definition: postmaster.c:348
static int sig
Definition: pg_ctl.c:79
static bool ThereIsAtLeastOneRole ( void  )
static

Definition at line 1195 of file postinit.c.

References AccessShareLock, AuthIdRelationId, ForwardScanDirection, heap_beginscan_catalog(), heap_close, heap_endscan(), heap_getnext(), heap_open(), and NULL.

Referenced by InitPostgres().

1196 {
1197  Relation pg_authid_rel;
1198  HeapScanDesc scan;
1199  bool result;
1200 
1201  pg_authid_rel = heap_open(AuthIdRelationId, AccessShareLock);
1202 
1203  scan = heap_beginscan_catalog(pg_authid_rel, 0, NULL);
1204  result = (heap_getnext(scan, ForwardScanDirection) != NULL);
1205 
1206  heap_endscan(scan);
1207  heap_close(pg_authid_rel, AccessShareLock);
1208 
1209  return result;
1210 }
void heap_endscan(HeapScanDesc scan)
Definition: heapam.c:1581
#define AccessShareLock
Definition: lockdefs.h:36
#define heap_close(r, l)
Definition: heapam.h:97
#define AuthIdRelationId
Definition: pg_authid.h:42
HeapScanDesc heap_beginscan_catalog(Relation relation, int nkeys, ScanKey key)
Definition: heapam.c:1402
HeapTuple heap_getnext(HeapScanDesc scan, ScanDirection direction)
Definition: heapam.c:1781
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define NULL
Definition: c.h:226