mirror of
https://github.com/postgres/postgres.git
synced 2025-11-10 17:42:29 +03:00
Standard pgindent run for 8.1.
This commit is contained in:
@@ -4,9 +4,9 @@
|
||||
* Routines for maintaining "flat file" images of the shared catalogs.
|
||||
*
|
||||
* We use flat files so that the postmaster and not-yet-fully-started
|
||||
* backends can look at the contents of pg_database, pg_authid, and
|
||||
* pg_auth_members for authentication purposes. This module is
|
||||
* responsible for keeping the flat-file images as nearly in sync with
|
||||
* backends can look at the contents of pg_database, pg_authid, and
|
||||
* pg_auth_members for authentication purposes. This module is
|
||||
* responsible for keeping the flat-file images as nearly in sync with
|
||||
* database reality as possible.
|
||||
*
|
||||
* The tricky part of the write_xxx_file() routines in this module is that
|
||||
@@ -23,7 +23,7 @@
|
||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/utils/init/flatfiles.c,v 1.14 2005/08/11 21:11:46 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/init/flatfiles.c,v 1.15 2005/10/15 02:49:33 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -55,7 +55,7 @@
|
||||
#define AUTH_FLAT_FILE "global/pg_auth"
|
||||
|
||||
/* Info bits in a flatfiles 2PC record */
|
||||
#define FF_BIT_DATABASE 1
|
||||
#define FF_BIT_DATABASE 1
|
||||
#define FF_BIT_AUTH 2
|
||||
|
||||
|
||||
@@ -181,8 +181,8 @@ write_database_file(Relation drel)
|
||||
|
||||
/*
|
||||
* Create a temporary filename to be renamed later. This prevents the
|
||||
* backend from clobbering the flat file while the postmaster
|
||||
* might be reading from it.
|
||||
* backend from clobbering the flat file while the postmaster might be
|
||||
* reading from it.
|
||||
*/
|
||||
filename = database_getflatfilename();
|
||||
bufsize = strlen(filename) + 12;
|
||||
@@ -209,7 +209,7 @@ write_database_file(Relation drel)
|
||||
Oid datoid;
|
||||
Oid dattablespace;
|
||||
TransactionId datfrozenxid,
|
||||
datvacuumxid;
|
||||
datvacuumxid;
|
||||
|
||||
datname = NameStr(dbform->datname);
|
||||
datoid = HeapTupleGetOid(tuple);
|
||||
@@ -219,7 +219,7 @@ write_database_file(Relation drel)
|
||||
|
||||
/*
|
||||
* Identify the oldest datfrozenxid, ignoring databases that are not
|
||||
* connectable (we assume they are safely frozen). This must match
|
||||
* connectable (we assume they are safely frozen). This must match
|
||||
* the logic in vac_truncate_clog() in vacuum.c.
|
||||
*/
|
||||
if (dbform->datallowconn &&
|
||||
@@ -262,8 +262,8 @@ write_database_file(Relation drel)
|
||||
tempname)));
|
||||
|
||||
/*
|
||||
* Rename the temp file to its final name, deleting the old flat file.
|
||||
* We expect that rename(2) is an atomic action.
|
||||
* Rename the temp file to its final name, deleting the old flat file. We
|
||||
* expect that rename(2) is an atomic action.
|
||||
*/
|
||||
if (rename(tempname, filename))
|
||||
ereport(ERROR,
|
||||
@@ -295,16 +295,18 @@ write_database_file(Relation drel)
|
||||
* and build data structures in-memory before writing the file.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
Oid roleid;
|
||||
bool rolcanlogin;
|
||||
char* rolname;
|
||||
char* rolpassword;
|
||||
char* rolvaliduntil;
|
||||
List* member_of;
|
||||
char *rolname;
|
||||
char *rolpassword;
|
||||
char *rolvaliduntil;
|
||||
List *member_of;
|
||||
} auth_entry;
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
Oid roleid;
|
||||
Oid memberid;
|
||||
} authmem_entry;
|
||||
@@ -314,11 +316,13 @@ typedef struct {
|
||||
static int
|
||||
oid_compar(const void *a, const void *b)
|
||||
{
|
||||
const auth_entry *a_auth = (const auth_entry*) a;
|
||||
const auth_entry *b_auth = (const auth_entry*) b;
|
||||
const auth_entry *a_auth = (const auth_entry *) a;
|
||||
const auth_entry *b_auth = (const auth_entry *) b;
|
||||
|
||||
if (a_auth->roleid < b_auth->roleid) return -1;
|
||||
if (a_auth->roleid > b_auth->roleid) return 1;
|
||||
if (a_auth->roleid < b_auth->roleid)
|
||||
return -1;
|
||||
if (a_auth->roleid > b_auth->roleid)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -326,21 +330,23 @@ oid_compar(const void *a, const void *b)
|
||||
static int
|
||||
name_compar(const void *a, const void *b)
|
||||
{
|
||||
const auth_entry *a_auth = (const auth_entry*) a;
|
||||
const auth_entry *b_auth = (const auth_entry*) b;
|
||||
const auth_entry *a_auth = (const auth_entry *) a;
|
||||
const auth_entry *b_auth = (const auth_entry *) b;
|
||||
|
||||
return strcmp(a_auth->rolname,b_auth->rolname);
|
||||
return strcmp(a_auth->rolname, b_auth->rolname);
|
||||
}
|
||||
|
||||
/* qsort comparator for sorting authmem_entry array by memberid */
|
||||
static int
|
||||
mem_compar(const void *a, const void *b)
|
||||
{
|
||||
const authmem_entry *a_auth = (const authmem_entry*) a;
|
||||
const authmem_entry *b_auth = (const authmem_entry*) b;
|
||||
const authmem_entry *a_auth = (const authmem_entry *) a;
|
||||
const authmem_entry *b_auth = (const authmem_entry *) b;
|
||||
|
||||
if (a_auth->memberid < b_auth->memberid) return -1;
|
||||
if (a_auth->memberid > b_auth->memberid) return 1;
|
||||
if (a_auth->memberid < b_auth->memberid)
|
||||
return -1;
|
||||
if (a_auth->memberid > b_auth->memberid)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -354,7 +360,7 @@ write_auth_file(Relation rel_authid, Relation rel_authmem)
|
||||
char *filename,
|
||||
*tempname;
|
||||
int bufsize;
|
||||
BlockNumber totalblocks;
|
||||
BlockNumber totalblocks;
|
||||
FILE *fp;
|
||||
mode_t oumask;
|
||||
HeapScanDesc scan;
|
||||
@@ -364,13 +370,13 @@ write_auth_file(Relation rel_authid, Relation rel_authmem)
|
||||
int curr_mem = 0;
|
||||
int total_mem = 0;
|
||||
int est_rows;
|
||||
auth_entry *auth_info;
|
||||
auth_entry *auth_info;
|
||||
authmem_entry *authmem_info;
|
||||
|
||||
/*
|
||||
* Create a temporary filename to be renamed later. This prevents the
|
||||
* backend from clobbering the flat file while the postmaster might
|
||||
* be reading from it.
|
||||
* backend from clobbering the flat file while the postmaster might be
|
||||
* reading from it.
|
||||
*/
|
||||
filename = auth_getflatfilename();
|
||||
bufsize = strlen(filename) + 12;
|
||||
@@ -387,29 +393,29 @@ write_auth_file(Relation rel_authid, Relation rel_authmem)
|
||||
tempname)));
|
||||
|
||||
/*
|
||||
* Read pg_authid and fill temporary data structures. Note we must
|
||||
* read all roles, even those without rolcanlogin.
|
||||
* Read pg_authid and fill temporary data structures. Note we must read
|
||||
* all roles, even those without rolcanlogin.
|
||||
*/
|
||||
totalblocks = RelationGetNumberOfBlocks(rel_authid);
|
||||
totalblocks = totalblocks ? totalblocks : 1;
|
||||
est_rows = totalblocks * (BLCKSZ / (sizeof(HeapTupleHeaderData)+sizeof(FormData_pg_authid)));
|
||||
auth_info = (auth_entry*) palloc(est_rows*sizeof(auth_entry));
|
||||
est_rows = totalblocks * (BLCKSZ / (sizeof(HeapTupleHeaderData) + sizeof(FormData_pg_authid)));
|
||||
auth_info = (auth_entry *) palloc(est_rows * sizeof(auth_entry));
|
||||
|
||||
scan = heap_beginscan(rel_authid, SnapshotNow, 0, NULL);
|
||||
while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
Form_pg_authid aform = (Form_pg_authid) GETSTRUCT(tuple);
|
||||
HeapTupleHeader tup = tuple->t_data;
|
||||
char *tp; /* ptr to tuple data */
|
||||
long off; /* offset in tuple data */
|
||||
char *tp; /* ptr to tuple data */
|
||||
long off; /* offset in tuple data */
|
||||
bits8 *bp = tup->t_bits; /* ptr to null bitmask in tuple */
|
||||
Datum datum;
|
||||
|
||||
if (curr_role >= est_rows)
|
||||
{
|
||||
est_rows *= 2;
|
||||
auth_info = (auth_entry*)
|
||||
repalloc(auth_info, est_rows*sizeof(auth_entry));
|
||||
auth_info = (auth_entry *)
|
||||
repalloc(auth_info, est_rows * sizeof(auth_entry));
|
||||
}
|
||||
|
||||
auth_info[curr_role].roleid = HeapTupleGetOid(tuple);
|
||||
@@ -418,10 +424,10 @@ write_auth_file(Relation rel_authid, Relation rel_authmem)
|
||||
auth_info[curr_role].member_of = NIL;
|
||||
|
||||
/*
|
||||
* We can't use heap_getattr() here because during startup we will
|
||||
* not have any tupdesc for pg_authid. Fortunately it's not too
|
||||
* hard to work around this. rolpassword is the first possibly-null
|
||||
* field so we can compute its offset directly.
|
||||
* We can't use heap_getattr() here because during startup we will not
|
||||
* have any tupdesc for pg_authid. Fortunately it's not too hard to
|
||||
* work around this. rolpassword is the first possibly-null field so
|
||||
* we can compute its offset directly.
|
||||
*/
|
||||
tp = (char *) tup + tup->t_hoff;
|
||||
off = offsetof(FormData_pg_authid, rolpassword);
|
||||
@@ -438,8 +444,8 @@ write_auth_file(Relation rel_authid, Relation rel_authmem)
|
||||
datum = PointerGetDatum(tp + off);
|
||||
|
||||
/*
|
||||
* The password probably shouldn't ever be out-of-line toasted;
|
||||
* if it is, ignore it, since we can't handle that in startup mode.
|
||||
* The password probably shouldn't ever be out-of-line toasted; if
|
||||
* it is, ignore it, since we can't handle that in startup mode.
|
||||
*/
|
||||
if (VARATT_IS_EXTERNAL(DatumGetPointer(datum)))
|
||||
auth_info[curr_role].rolpassword = pstrdup("");
|
||||
@@ -495,8 +501,8 @@ write_auth_file(Relation rel_authid, Relation rel_authmem)
|
||||
*/
|
||||
totalblocks = RelationGetNumberOfBlocks(rel_authmem);
|
||||
totalblocks = totalblocks ? totalblocks : 1;
|
||||
est_rows = totalblocks * (BLCKSZ / (sizeof(HeapTupleHeaderData)+sizeof(FormData_pg_auth_members)));
|
||||
authmem_info = (authmem_entry*) palloc(est_rows*sizeof(authmem_entry));
|
||||
est_rows = totalblocks * (BLCKSZ / (sizeof(HeapTupleHeaderData) + sizeof(FormData_pg_auth_members)));
|
||||
authmem_info = (authmem_entry *) palloc(est_rows * sizeof(authmem_entry));
|
||||
|
||||
scan = heap_beginscan(rel_authmem, SnapshotNow, 0, NULL);
|
||||
while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
@@ -506,8 +512,8 @@ write_auth_file(Relation rel_authid, Relation rel_authmem)
|
||||
if (curr_mem >= est_rows)
|
||||
{
|
||||
est_rows *= 2;
|
||||
authmem_info = (authmem_entry*)
|
||||
repalloc(authmem_info, est_rows*sizeof(authmem_entry));
|
||||
authmem_info = (authmem_entry *)
|
||||
repalloc(authmem_info, est_rows * sizeof(authmem_entry));
|
||||
}
|
||||
|
||||
authmem_info[curr_mem].roleid = memform->roleid;
|
||||
@@ -518,8 +524,8 @@ write_auth_file(Relation rel_authid, Relation rel_authmem)
|
||||
heap_endscan(scan);
|
||||
|
||||
/*
|
||||
* Search for memberships. We can skip all this if pg_auth_members
|
||||
* is empty.
|
||||
* Search for memberships. We can skip all this if pg_auth_members is
|
||||
* empty.
|
||||
*/
|
||||
if (total_mem > 0)
|
||||
{
|
||||
@@ -528,22 +534,23 @@ write_auth_file(Relation rel_authid, Relation rel_authmem)
|
||||
*/
|
||||
qsort(auth_info, total_roles, sizeof(auth_entry), oid_compar);
|
||||
qsort(authmem_info, total_mem, sizeof(authmem_entry), mem_compar);
|
||||
|
||||
/*
|
||||
* For each role, find what it belongs to.
|
||||
*/
|
||||
for (curr_role = 0; curr_role < total_roles; curr_role++)
|
||||
{
|
||||
List *roles_list;
|
||||
List *roles_names_list = NIL;
|
||||
ListCell *mem;
|
||||
List *roles_list;
|
||||
List *roles_names_list = NIL;
|
||||
ListCell *mem;
|
||||
|
||||
/* We can skip this for non-login roles */
|
||||
if (!auth_info[curr_role].rolcanlogin)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* This search algorithm is the same as in is_member_of_role;
|
||||
* we are just working with a different input data structure.
|
||||
* This search algorithm is the same as in is_member_of_role; we
|
||||
* are just working with a different input data structure.
|
||||
*/
|
||||
roles_list = list_make1_oid(auth_info[curr_role].roleid);
|
||||
|
||||
@@ -551,17 +558,20 @@ write_auth_file(Relation rel_authid, Relation rel_authmem)
|
||||
{
|
||||
authmem_entry key;
|
||||
authmem_entry *found_mem;
|
||||
int first_found, last_found, i;
|
||||
int first_found,
|
||||
last_found,
|
||||
i;
|
||||
|
||||
key.memberid = lfirst_oid(mem);
|
||||
found_mem = bsearch(&key, authmem_info, total_mem,
|
||||
sizeof(authmem_entry), mem_compar);
|
||||
if (!found_mem)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* bsearch found a match for us; but if there were
|
||||
* multiple matches it could have found any one of them.
|
||||
* Locate first and last match.
|
||||
* bsearch found a match for us; but if there were multiple
|
||||
* matches it could have found any one of them. Locate first
|
||||
* and last match.
|
||||
*/
|
||||
first_found = last_found = (found_mem - authmem_info);
|
||||
while (first_found > 0 &&
|
||||
@@ -570,30 +580,31 @@ write_auth_file(Relation rel_authid, Relation rel_authmem)
|
||||
while (last_found + 1 < total_mem &&
|
||||
mem_compar(&key, &authmem_info[last_found + 1]) == 0)
|
||||
last_found++;
|
||||
|
||||
/*
|
||||
* Now add all the new roles to roles_list.
|
||||
*/
|
||||
for (i = first_found; i <= last_found; i++)
|
||||
roles_list = list_append_unique_oid(roles_list,
|
||||
authmem_info[i].roleid);
|
||||
authmem_info[i].roleid);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert list of role Oids to list of role names.
|
||||
* We must do this before re-sorting auth_info.
|
||||
* Convert list of role Oids to list of role names. We must do
|
||||
* this before re-sorting auth_info.
|
||||
*
|
||||
* We skip the first list element (curr_role itself) since there
|
||||
* is no point in writing that a role is a member of itself.
|
||||
* We skip the first list element (curr_role itself) since there is
|
||||
* no point in writing that a role is a member of itself.
|
||||
*/
|
||||
for_each_cell(mem, lnext(list_head(roles_list)))
|
||||
{
|
||||
auth_entry key_auth;
|
||||
auth_entry key_auth;
|
||||
auth_entry *found_role;
|
||||
|
||||
key_auth.roleid = lfirst_oid(mem);
|
||||
found_role = bsearch(&key_auth, auth_info, total_roles,
|
||||
sizeof(auth_entry), oid_compar);
|
||||
if (found_role) /* paranoia */
|
||||
if (found_role) /* paranoia */
|
||||
roles_names_list = lappend(roles_names_list,
|
||||
found_role->rolname);
|
||||
}
|
||||
@@ -613,7 +624,7 @@ write_auth_file(Relation rel_authid, Relation rel_authmem)
|
||||
|
||||
if (arole->rolcanlogin)
|
||||
{
|
||||
ListCell *mem;
|
||||
ListCell *mem;
|
||||
|
||||
fputs_quote(arole->rolname, fp);
|
||||
fputs(" ", fp);
|
||||
@@ -638,8 +649,8 @@ write_auth_file(Relation rel_authid, Relation rel_authmem)
|
||||
tempname)));
|
||||
|
||||
/*
|
||||
* Rename the temp file to its final name, deleting the old flat file.
|
||||
* We expect that rename(2) is an atomic action.
|
||||
* Rename the temp file to its final name, deleting the old flat file. We
|
||||
* expect that rename(2) is an atomic action.
|
||||
*/
|
||||
if (rename(tempname, filename))
|
||||
ereport(ERROR,
|
||||
@@ -671,11 +682,13 @@ BuildFlatFiles(bool database_only)
|
||||
{
|
||||
ResourceOwner owner;
|
||||
RelFileNode rnode;
|
||||
Relation rel_db, rel_authid, rel_authmem;
|
||||
Relation rel_db,
|
||||
rel_authid,
|
||||
rel_authmem;
|
||||
|
||||
/*
|
||||
* We don't have any hope of running a real relcache, but we can use
|
||||
* the same fake-relcache facility that WAL replay uses.
|
||||
* We don't have any hope of running a real relcache, but we can use the
|
||||
* same fake-relcache facility that WAL replay uses.
|
||||
*/
|
||||
XLogInitRelationCache();
|
||||
|
||||
@@ -749,21 +762,21 @@ AtEOXact_UpdateFlatFiles(bool isCommit)
|
||||
}
|
||||
|
||||
/*
|
||||
* Advance command counter to be certain we see all effects of the
|
||||
* current transaction.
|
||||
* Advance command counter to be certain we see all effects of the current
|
||||
* transaction.
|
||||
*/
|
||||
CommandCounterIncrement();
|
||||
|
||||
/*
|
||||
* We use ExclusiveLock to ensure that only one backend writes the
|
||||
* flat file(s) at a time. That's sufficient because it's okay to
|
||||
* allow plain reads of the tables in parallel. There is some chance
|
||||
* of a deadlock here (if we were triggered by a user update of one
|
||||
* of the tables, which likely won't have gotten a strong enough lock),
|
||||
* so get the locks we need before writing anything.
|
||||
* We use ExclusiveLock to ensure that only one backend writes the flat
|
||||
* file(s) at a time. That's sufficient because it's okay to allow plain
|
||||
* reads of the tables in parallel. There is some chance of a deadlock
|
||||
* here (if we were triggered by a user update of one of the tables, which
|
||||
* likely won't have gotten a strong enough lock), so get the locks we
|
||||
* need before writing anything.
|
||||
*
|
||||
* For writing the auth file, it's sufficient to ExclusiveLock pg_authid;
|
||||
* we take just regular AccessShareLock on pg_auth_members.
|
||||
* For writing the auth file, it's sufficient to ExclusiveLock pg_authid; we
|
||||
* take just regular AccessShareLock on pg_auth_members.
|
||||
*/
|
||||
if (database_file_update_subid != InvalidSubTransactionId)
|
||||
drel = heap_open(DatabaseRelationId, ExclusiveLock);
|
||||
@@ -863,7 +876,7 @@ AtEOSubXact_UpdateFlatFiles(bool isCommit,
|
||||
* or pg_auth_members via general-purpose INSERT/UPDATE/DELETE commands.
|
||||
*
|
||||
* It is sufficient for this to be a STATEMENT trigger since we don't
|
||||
* care which individual rows changed. It doesn't much matter whether
|
||||
* care which individual rows changed. It doesn't much matter whether
|
||||
* it's a BEFORE or AFTER trigger.
|
||||
*/
|
||||
Datum
|
||||
@@ -906,11 +919,11 @@ flatfile_twophase_postcommit(TransactionId xid, uint16 info,
|
||||
void *recdata, uint32 len)
|
||||
{
|
||||
/*
|
||||
* Set flags to do the needed file updates at the end of my own
|
||||
* current transaction. (XXX this has some issues if my own
|
||||
* transaction later rolls back, or if there is any significant
|
||||
* delay before I commit. OK for now because we disallow
|
||||
* COMMIT PREPARED inside a transaction block.)
|
||||
* Set flags to do the needed file updates at the end of my own current
|
||||
* transaction. (XXX this has some issues if my own transaction later
|
||||
* rolls back, or if there is any significant delay before I commit. OK
|
||||
* for now because we disallow COMMIT PREPARED inside a transaction
|
||||
* block.)
|
||||
*/
|
||||
if (info & FF_BIT_DATABASE)
|
||||
database_file_update_needed();
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.149 2005/08/17 22:14:33 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.150 2005/10/15 02:49:33 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -37,7 +37,7 @@
|
||||
#include "storage/ipc.h"
|
||||
#include "storage/pg_shmem.h"
|
||||
#include "storage/proc.h"
|
||||
#include "storage/procarray.h"
|
||||
#include "storage/procarray.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/guc.h"
|
||||
#include "utils/lsyscache.h"
|
||||
@@ -295,10 +295,10 @@ make_absolute_path(const char *path)
|
||||
* DEFINER functions, as well as locally in some specialized commands.
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
static Oid AuthenticatedUserId = InvalidOid;
|
||||
static Oid SessionUserId = InvalidOid;
|
||||
static Oid OuterUserId = InvalidOid;
|
||||
static Oid CurrentUserId = InvalidOid;
|
||||
static Oid AuthenticatedUserId = InvalidOid;
|
||||
static Oid SessionUserId = InvalidOid;
|
||||
static Oid OuterUserId = InvalidOid;
|
||||
static Oid CurrentUserId = InvalidOid;
|
||||
|
||||
/* We also have to remember the superuser state of some of these levels */
|
||||
static bool AuthenticatedUserIsSuperuser = false;
|
||||
@@ -418,8 +418,8 @@ InitializeSessionUserId(const char *rolename)
|
||||
|
||||
/*
|
||||
* These next checks are not enforced when in standalone mode, so that
|
||||
* there is a way to recover from sillinesses like
|
||||
* "UPDATE pg_authid SET rolcanlogin = false;".
|
||||
* there is a way to recover from sillinesses like "UPDATE pg_authid SET
|
||||
* rolcanlogin = false;".
|
||||
*
|
||||
* We do not enforce them for the autovacuum process either.
|
||||
*/
|
||||
@@ -433,15 +433,16 @@ InitializeSessionUserId(const char *rolename)
|
||||
(errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
|
||||
errmsg("role \"%s\" is not permitted to log in",
|
||||
rolename)));
|
||||
|
||||
/*
|
||||
* Check connection limit for this role.
|
||||
*
|
||||
* There is a race condition here --- we create our PGPROC before
|
||||
* checking for other PGPROCs. If two backends did this at about the
|
||||
* checking for other PGPROCs. If two backends did this at about the
|
||||
* same time, they might both think they were over the limit, while
|
||||
* ideally one should succeed and one fail. Getting that to work
|
||||
* exactly seems more trouble than it is worth, however; instead
|
||||
* we just document that the connection limit is approximate.
|
||||
* exactly seems more trouble than it is worth, however; instead we
|
||||
* just document that the connection limit is approximate.
|
||||
*/
|
||||
if (rform->rolconnlimit >= 0 &&
|
||||
!AuthenticatedUserIsSuperuser &&
|
||||
@@ -451,7 +452,7 @@ InitializeSessionUserId(const char *rolename)
|
||||
errmsg("too many connections for role \"%s\"",
|
||||
rolename)));
|
||||
}
|
||||
|
||||
|
||||
/* Record username and superuser status as GUC settings too */
|
||||
SetConfigOption("session_authorization", rolename,
|
||||
PGC_BACKEND, PGC_S_OVERRIDE);
|
||||
@@ -460,9 +461,8 @@ InitializeSessionUserId(const char *rolename)
|
||||
PGC_INTERNAL, PGC_S_OVERRIDE);
|
||||
|
||||
/*
|
||||
* Set up user-specific configuration variables. This is a good place
|
||||
* to do it so we don't have to read pg_authid twice during session
|
||||
* startup.
|
||||
* Set up user-specific configuration variables. This is a good place to
|
||||
* do it so we don't have to read pg_authid twice during session startup.
|
||||
*/
|
||||
datum = SysCacheGetAttr(AUTHNAME, roleTup,
|
||||
Anum_pg_authid_rolconfig, &isnull);
|
||||
@@ -534,7 +534,7 @@ SetSessionAuthorization(Oid userid, bool is_superuser)
|
||||
!AuthenticatedUserIsSuperuser)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
errmsg("permission denied to set session authorization")));
|
||||
errmsg("permission denied to set session authorization")));
|
||||
|
||||
SetSessionUserId(userid, is_superuser);
|
||||
|
||||
@@ -562,7 +562,7 @@ GetCurrentRoleId(void)
|
||||
* Change Role ID while running (SET ROLE)
|
||||
*
|
||||
* If roleid is InvalidOid, we are doing SET ROLE NONE: revert to the
|
||||
* session user authorization. In this case the is_superuser argument
|
||||
* session user authorization. In this case the is_superuser argument
|
||||
* is ignored.
|
||||
*
|
||||
* When roleid is not InvalidOid, the caller must have checked whether
|
||||
@@ -686,17 +686,17 @@ CreateLockFile(const char *filename, bool amPostmaster,
|
||||
pid_t my_pid = getpid();
|
||||
|
||||
/*
|
||||
* We need a loop here because of race conditions. But don't loop
|
||||
* forever (for example, a non-writable $PGDATA directory might cause
|
||||
* a failure that won't go away). 100 tries seems like plenty.
|
||||
* We need a loop here because of race conditions. But don't loop forever
|
||||
* (for example, a non-writable $PGDATA directory might cause a failure
|
||||
* that won't go away). 100 tries seems like plenty.
|
||||
*/
|
||||
for (ntries = 0;; ntries++)
|
||||
{
|
||||
/*
|
||||
* Try to create the lock file --- O_EXCL makes this atomic.
|
||||
*
|
||||
* Think not to make the file protection weaker than 0600. See
|
||||
* comments below.
|
||||
* Think not to make the file protection weaker than 0600. See comments
|
||||
* below.
|
||||
*/
|
||||
fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
|
||||
if (fd >= 0)
|
||||
@@ -745,38 +745,38 @@ CreateLockFile(const char *filename, bool amPostmaster,
|
||||
/*
|
||||
* Check to see if the other process still exists
|
||||
*
|
||||
* If the PID in the lockfile is our own PID or our parent's PID,
|
||||
* then the file must be stale (probably left over from a previous
|
||||
* system boot cycle). We need this test because of the likelihood
|
||||
* that a reboot will assign exactly the same PID as we had in the
|
||||
* previous reboot. Also, if there is just one more process launch
|
||||
* in this reboot than in the previous one, the lockfile might mention
|
||||
* our parent's PID. We can reject that since we'd never be launched
|
||||
* directly by a competing postmaster. We can't detect grandparent
|
||||
* processes unfortunately, but if the init script is written carefully
|
||||
* then all but the immediate parent shell will be root-owned processes
|
||||
* and so the kill test will fail with EPERM.
|
||||
* If the PID in the lockfile is our own PID or our parent's PID, then
|
||||
* the file must be stale (probably left over from a previous system
|
||||
* boot cycle). We need this test because of the likelihood that a
|
||||
* reboot will assign exactly the same PID as we had in the previous
|
||||
* reboot. Also, if there is just one more process launch in this
|
||||
* reboot than in the previous one, the lockfile might mention our
|
||||
* parent's PID. We can reject that since we'd never be launched
|
||||
* directly by a competing postmaster. We can't detect grandparent
|
||||
* processes unfortunately, but if the init script is written
|
||||
* carefully then all but the immediate parent shell will be
|
||||
* root-owned processes and so the kill test will fail with EPERM.
|
||||
*
|
||||
* We can treat the EPERM-error case as okay because that error implies
|
||||
* that the existing process has a different userid than we do, which
|
||||
* means it cannot be a competing postmaster. A postmaster cannot
|
||||
* successfully attach to a data directory owned by a userid other
|
||||
* than its own. (This is now checked directly in checkDataDir(),
|
||||
* but has been true for a long time because of the restriction that
|
||||
* the data directory isn't group- or world-accessible.) Also,
|
||||
* since we create the lockfiles mode 600, we'd have failed above
|
||||
* if the lockfile belonged to another userid --- which means that
|
||||
* whatever process kill() is reporting about isn't the one that
|
||||
* made the lockfile. (NOTE: this last consideration is the only
|
||||
* one that keeps us from blowing away a Unix socket file belonging
|
||||
* to an instance of Postgres being run by someone else, at least
|
||||
* on machines where /tmp hasn't got a stickybit.)
|
||||
* than its own. (This is now checked directly in checkDataDir(), but
|
||||
* has been true for a long time because of the restriction that the
|
||||
* data directory isn't group- or world-accessible.) Also, since we
|
||||
* create the lockfiles mode 600, we'd have failed above if the
|
||||
* lockfile belonged to another userid --- which means that whatever
|
||||
* process kill() is reporting about isn't the one that made the
|
||||
* lockfile. (NOTE: this last consideration is the only one that
|
||||
* keeps us from blowing away a Unix socket file belonging to an
|
||||
* instance of Postgres being run by someone else, at least on
|
||||
* machines where /tmp hasn't got a stickybit.)
|
||||
*
|
||||
* Windows hasn't got getppid(), but doesn't need it since it's not
|
||||
* using real kill() either...
|
||||
* Windows hasn't got getppid(), but doesn't need it since it's not using
|
||||
* real kill() either...
|
||||
*
|
||||
* Normally kill() will fail with ESRCH if the given PID doesn't
|
||||
* exist. BeOS returns EINVAL for some silly reason, however.
|
||||
* Normally kill() will fail with ESRCH if the given PID doesn't exist.
|
||||
* BeOS returns EINVAL for some silly reason, however.
|
||||
*/
|
||||
if (other_pid != my_pid
|
||||
#ifndef WIN32
|
||||
@@ -811,11 +811,11 @@ CreateLockFile(const char *filename, bool amPostmaster,
|
||||
}
|
||||
|
||||
/*
|
||||
* No, the creating process did not exist. However, it could be
|
||||
* that the postmaster crashed (or more likely was kill -9'd by a
|
||||
* clueless admin) but has left orphan backends behind. Check for
|
||||
* this by looking to see if there is an associated shmem segment
|
||||
* that is still in use.
|
||||
* No, the creating process did not exist. However, it could be that
|
||||
* the postmaster crashed (or more likely was kill -9'd by a clueless
|
||||
* admin) but has left orphan backends behind. Check for this by
|
||||
* looking to see if there is an associated shmem segment that is
|
||||
* still in use.
|
||||
*/
|
||||
if (isDDLock)
|
||||
{
|
||||
@@ -833,23 +833,23 @@ CreateLockFile(const char *filename, bool amPostmaster,
|
||||
if (PGSharedMemoryIsInUse(id1, id2))
|
||||
ereport(FATAL,
|
||||
(errcode(ERRCODE_LOCK_FILE_EXISTS),
|
||||
errmsg("pre-existing shared memory block "
|
||||
"(key %lu, ID %lu) is still in use",
|
||||
id1, id2),
|
||||
errhint("If you're sure there are no old "
|
||||
"server processes still running, remove "
|
||||
"the shared memory block with "
|
||||
"the command \"ipcclean\", \"ipcrm\", "
|
||||
"or just delete the file \"%s\".",
|
||||
filename)));
|
||||
errmsg("pre-existing shared memory block "
|
||||
"(key %lu, ID %lu) is still in use",
|
||||
id1, id2),
|
||||
errhint("If you're sure there are no old "
|
||||
"server processes still running, remove "
|
||||
"the shared memory block with "
|
||||
"the command \"ipcclean\", \"ipcrm\", "
|
||||
"or just delete the file \"%s\".",
|
||||
filename)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Looks like nobody's home. Unlink the file and try again to
|
||||
* create it. Need a loop because of possible race condition
|
||||
* against other would-be creators.
|
||||
* Looks like nobody's home. Unlink the file and try again to create
|
||||
* it. Need a loop because of possible race condition against other
|
||||
* would-be creators.
|
||||
*/
|
||||
if (unlink(filename) < 0)
|
||||
ereport(FATAL,
|
||||
@@ -857,7 +857,7 @@ CreateLockFile(const char *filename, bool amPostmaster,
|
||||
errmsg("could not remove old lock file \"%s\": %m",
|
||||
filename),
|
||||
errhint("The file seems accidentally left over, but "
|
||||
"it could not be removed. Please remove the file "
|
||||
"it could not be removed. Please remove the file "
|
||||
"by hand and try again.")));
|
||||
}
|
||||
|
||||
@@ -878,7 +878,7 @@ CreateLockFile(const char *filename, bool amPostmaster,
|
||||
errno = save_errno ? save_errno : ENOSPC;
|
||||
ereport(FATAL,
|
||||
(errcode_for_file_access(),
|
||||
errmsg("could not write lock file \"%s\": %m", filename)));
|
||||
errmsg("could not write lock file \"%s\": %m", filename)));
|
||||
}
|
||||
if (close(fd))
|
||||
{
|
||||
@@ -888,7 +888,7 @@ CreateLockFile(const char *filename, bool amPostmaster,
|
||||
errno = save_errno;
|
||||
ereport(FATAL,
|
||||
(errcode_for_file_access(),
|
||||
errmsg("could not write lock file \"%s\": %m", filename)));
|
||||
errmsg("could not write lock file \"%s\": %m", filename)));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -939,10 +939,10 @@ TouchSocketLockFile(void)
|
||||
if (socketLockFile[0] != '\0')
|
||||
{
|
||||
/*
|
||||
* utime() is POSIX standard, utimes() is a common alternative; if
|
||||
* we have neither, fall back to actually reading the file (which
|
||||
* only sets the access time not mod time, but that should be
|
||||
* enough in most cases). In all paths, we ignore errors.
|
||||
* utime() is POSIX standard, utimes() is a common alternative; if we
|
||||
* have neither, fall back to actually reading the file (which only
|
||||
* sets the access time not mod time, but that should be enough in
|
||||
* most cases). In all paths, we ignore errors.
|
||||
*/
|
||||
#ifdef HAVE_UTIME
|
||||
utime(socketLockFile, NULL);
|
||||
@@ -1093,7 +1093,7 @@ ValidatePgVersion(const char *path)
|
||||
else
|
||||
ereport(FATAL,
|
||||
(errcode_for_file_access(),
|
||||
errmsg("could not open file \"%s\": %m", full_path)));
|
||||
errmsg("could not open file \"%s\": %m", full_path)));
|
||||
}
|
||||
|
||||
ret = fscanf(file, "%ld.%ld", &file_major, &file_minor);
|
||||
@@ -1113,7 +1113,7 @@ ValidatePgVersion(const char *path)
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("database files are incompatible with server"),
|
||||
errdetail("The data directory was initialized by PostgreSQL version %ld.%ld, "
|
||||
"which is not compatible with this version %s.",
|
||||
"which is not compatible with this version %s.",
|
||||
file_major, file_minor, version_string)));
|
||||
}
|
||||
|
||||
@@ -1149,7 +1149,7 @@ process_preload_libraries(char *preload_libraries_string)
|
||||
list_free(elemlist);
|
||||
ereport(LOG,
|
||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||
errmsg("invalid list syntax for parameter \"preload_libraries\"")));
|
||||
errmsg("invalid list syntax for parameter \"preload_libraries\"")));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1164,9 +1164,8 @@ process_preload_libraries(char *preload_libraries_string)
|
||||
if (sep)
|
||||
{
|
||||
/*
|
||||
* a colon separator implies there is an initialization
|
||||
* function that we need to run in addition to loading the
|
||||
* library
|
||||
* a colon separator implies there is an initialization function
|
||||
* that we need to run in addition to loading the library
|
||||
*/
|
||||
size_t filename_len = sep - tok;
|
||||
size_t funcname_len = strlen(tok) - filename_len - 1;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.157 2005/08/11 21:11:46 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.158 2005/10/15 02:49:33 momjian Exp $
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
@@ -112,7 +112,7 @@ FindMyDatabase(const char *name, Oid *db_id, Oid *db_tablespace)
|
||||
*
|
||||
* Since FindMyDatabase cannot lock pg_database, the information it read
|
||||
* could be stale; for example we might have attached to a database that's in
|
||||
* process of being destroyed by dropdb(). This routine is called after
|
||||
* process of being destroyed by dropdb(). This routine is called after
|
||||
* we have all the locking and other infrastructure running --- now we can
|
||||
* check that we are really attached to a valid database.
|
||||
*
|
||||
@@ -134,14 +134,14 @@ static void
|
||||
ReverifyMyDatabase(const char *name)
|
||||
{
|
||||
Relation pgdbrel;
|
||||
SysScanDesc pgdbscan;
|
||||
SysScanDesc pgdbscan;
|
||||
ScanKeyData key;
|
||||
HeapTuple tup;
|
||||
Form_pg_database dbform;
|
||||
|
||||
/*
|
||||
* Because we grab RowShareLock here, we can be sure that dropdb()
|
||||
* is not running in parallel with us (any more).
|
||||
* Because we grab RowShareLock here, we can be sure that dropdb() is not
|
||||
* running in parallel with us (any more).
|
||||
*/
|
||||
pgdbrel = heap_open(DatabaseRelationId, RowShareLock);
|
||||
|
||||
@@ -161,17 +161,17 @@ ReverifyMyDatabase(const char *name)
|
||||
heap_close(pgdbrel, RowShareLock);
|
||||
|
||||
/*
|
||||
* The only real problem I could have created is to load dirty
|
||||
* buffers for the dead database into shared buffer cache; if I
|
||||
* did, some other backend will eventually try to write them and
|
||||
* die in mdblindwrt. Flush any such pages to forestall trouble.
|
||||
* The only real problem I could have created is to load dirty buffers
|
||||
* for the dead database into shared buffer cache; if I did, some
|
||||
* other backend will eventually try to write them and die in
|
||||
* mdblindwrt. Flush any such pages to forestall trouble.
|
||||
*/
|
||||
DropBuffers(MyDatabaseId);
|
||||
/* Now I can commit hara-kiri with a clear conscience... */
|
||||
ereport(FATAL,
|
||||
(errcode(ERRCODE_UNDEFINED_DATABASE),
|
||||
errmsg("database \"%s\", OID %u, has disappeared from pg_database",
|
||||
name, MyDatabaseId)));
|
||||
errmsg("database \"%s\", OID %u, has disappeared from pg_database",
|
||||
name, MyDatabaseId)));
|
||||
}
|
||||
|
||||
dbform = (Form_pg_database) GETSTRUCT(tup);
|
||||
@@ -191,17 +191,18 @@ ReverifyMyDatabase(const char *name)
|
||||
if (!dbform->datallowconn)
|
||||
ereport(FATAL,
|
||||
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
||||
errmsg("database \"%s\" is not currently accepting connections",
|
||||
name)));
|
||||
errmsg("database \"%s\" is not currently accepting connections",
|
||||
name)));
|
||||
|
||||
/*
|
||||
* Check connection limit for this database.
|
||||
*
|
||||
* There is a race condition here --- we create our PGPROC before
|
||||
* checking for other PGPROCs. If two backends did this at about the
|
||||
* checking for other PGPROCs. If two backends did this at about the
|
||||
* same time, they might both think they were over the limit, while
|
||||
* ideally one should succeed and one fail. Getting that to work
|
||||
* exactly seems more trouble than it is worth, however; instead
|
||||
* we just document that the connection limit is approximate.
|
||||
* exactly seems more trouble than it is worth, however; instead we
|
||||
* just document that the connection limit is approximate.
|
||||
*/
|
||||
if (dbform->datconnlimit >= 0 &&
|
||||
!superuser() &&
|
||||
@@ -213,8 +214,8 @@ ReverifyMyDatabase(const char *name)
|
||||
}
|
||||
|
||||
/*
|
||||
* OK, we're golden. Next to-do item is to save the encoding
|
||||
* info out of the pg_database tuple.
|
||||
* OK, we're golden. Next to-do item is to save the encoding info out of
|
||||
* the pg_database tuple.
|
||||
*/
|
||||
SetDatabaseEncoding(dbform->encoding);
|
||||
/* Record it as a GUC internal option, too */
|
||||
@@ -264,8 +265,8 @@ InitCommunication(void)
|
||||
if (!IsUnderPostmaster) /* postmaster already did this */
|
||||
{
|
||||
/*
|
||||
* We're running a postgres bootstrap process or a standalone
|
||||
* backend. Create private "shmem" and semaphores.
|
||||
* We're running a postgres bootstrap process or a standalone backend.
|
||||
* Create private "shmem" and semaphores.
|
||||
*/
|
||||
CreateSharedMemoryAndSemaphores(true, 0);
|
||||
}
|
||||
@@ -309,7 +310,7 @@ BaseInit(void)
|
||||
* The return value indicates whether the userID is a superuser. (That
|
||||
* can only be tested inside a transaction, so we want to do it during
|
||||
* the startup transaction rather than doing a separate one in postgres.c.)
|
||||
*
|
||||
*
|
||||
* Note:
|
||||
* Be very careful with the order of calls in the InitPostgres function.
|
||||
* --------------------------------
|
||||
@@ -324,8 +325,8 @@ InitPostgres(const char *dbname, const char *username)
|
||||
/*
|
||||
* Set up the global variables holding database id and path.
|
||||
*
|
||||
* We take a shortcut in the bootstrap case, otherwise we have to look up
|
||||
* the db name in pg_database.
|
||||
* We take a shortcut in the bootstrap case, otherwise we have to look up the
|
||||
* db name in pg_database.
|
||||
*/
|
||||
if (bootstrap)
|
||||
{
|
||||
@@ -338,13 +339,12 @@ InitPostgres(const char *dbname, const char *username)
|
||||
char *fullpath;
|
||||
|
||||
/*
|
||||
* Formerly we validated DataDir here, but now that's done
|
||||
* earlier.
|
||||
* Formerly we validated DataDir here, but now that's done earlier.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Find oid and tablespace of the database we're about to open.
|
||||
* Since we're not yet up and running we have to use the hackish
|
||||
* Find oid and tablespace of the database we're about to open. Since
|
||||
* we're not yet up and running we have to use the hackish
|
||||
* FindMyDatabase.
|
||||
*/
|
||||
if (!FindMyDatabase(dbname, &MyDatabaseId, &MyDatabaseTableSpace))
|
||||
@@ -364,8 +364,8 @@ InitPostgres(const char *dbname, const char *username)
|
||||
(errcode(ERRCODE_UNDEFINED_DATABASE),
|
||||
errmsg("database \"%s\" does not exist",
|
||||
dbname),
|
||||
errdetail("The database subdirectory \"%s\" is missing.",
|
||||
fullpath)));
|
||||
errdetail("The database subdirectory \"%s\" is missing.",
|
||||
fullpath)));
|
||||
else
|
||||
ereport(FATAL,
|
||||
(errcode_for_file_access(),
|
||||
@@ -383,17 +383,17 @@ InitPostgres(const char *dbname, const char *username)
|
||||
*/
|
||||
|
||||
/*
|
||||
* Set up my per-backend PGPROC struct in shared memory. (We need
|
||||
* to know MyDatabaseId before we can do this, since it's entered into
|
||||
* the PGPROC struct.)
|
||||
* Set up my per-backend PGPROC struct in shared memory. (We need to
|
||||
* know MyDatabaseId before we can do this, since it's entered into the
|
||||
* PGPROC struct.)
|
||||
*/
|
||||
InitProcess();
|
||||
|
||||
/*
|
||||
* Initialize my entry in the shared-invalidation manager's array of
|
||||
* per-backend data. (Formerly this came before InitProcess, but now
|
||||
* it must happen after, because it uses MyProc.) Once I have done
|
||||
* this, I am visible to other backends!
|
||||
* per-backend data. (Formerly this came before InitProcess, but now it
|
||||
* must happen after, because it uses MyProc.) Once I have done this, I
|
||||
* am visible to other backends!
|
||||
*
|
||||
* Sets up MyBackendId, a unique backend identifier.
|
||||
*/
|
||||
@@ -410,22 +410,22 @@ InitPostgres(const char *dbname, const char *username)
|
||||
InitBufferPoolBackend();
|
||||
|
||||
/*
|
||||
* Initialize local process's access to XLOG. In bootstrap case we
|
||||
* may skip this since StartupXLOG() was run instead.
|
||||
* Initialize local process's access to XLOG. In bootstrap case we may
|
||||
* skip this since StartupXLOG() was run instead.
|
||||
*/
|
||||
if (!bootstrap)
|
||||
InitXLOGAccess();
|
||||
|
||||
/*
|
||||
* Initialize the relation descriptor cache. This must create at
|
||||
* least the minimum set of "nailed-in" cache entries. No catalog
|
||||
* access happens here.
|
||||
* Initialize the relation descriptor cache. This must create at least
|
||||
* the minimum set of "nailed-in" cache entries. No catalog access
|
||||
* happens here.
|
||||
*/
|
||||
RelationCacheInitialize();
|
||||
|
||||
/*
|
||||
* Initialize all the system catalog caches. Note that no catalog
|
||||
* access happens here; we only set up the cache structure.
|
||||
* Initialize all the system catalog caches. Note that no catalog access
|
||||
* happens here; we only set up the cache structure.
|
||||
*/
|
||||
InitCatalogCache();
|
||||
|
||||
@@ -433,14 +433,13 @@ InitPostgres(const char *dbname, const char *username)
|
||||
EnablePortalManager();
|
||||
|
||||
/*
|
||||
* Set up process-exit callback to do pre-shutdown cleanup. This
|
||||
* has to be after we've initialized all the low-level modules
|
||||
* like the buffer manager, because during shutdown this has to
|
||||
* run before the low-level modules start to close down. On the
|
||||
* other hand, we want it in place before we begin our first
|
||||
* transaction --- if we fail during the initialization transaction,
|
||||
* as is entirely possible, we need the AbortTransaction call to
|
||||
* clean up.
|
||||
* Set up process-exit callback to do pre-shutdown cleanup. This has to
|
||||
* be after we've initialized all the low-level modules like the buffer
|
||||
* manager, because during shutdown this has to run before the low-level
|
||||
* modules start to close down. On the other hand, we want it in place
|
||||
* before we begin our first transaction --- if we fail during the
|
||||
* initialization transaction, as is entirely possible, we need the
|
||||
* AbortTransaction call to clean up.
|
||||
*/
|
||||
on_shmem_exit(ShutdownPostgres, 0);
|
||||
|
||||
@@ -479,18 +478,18 @@ InitPostgres(const char *dbname, const char *username)
|
||||
}
|
||||
|
||||
/*
|
||||
* Unless we are bootstrapping, double-check that InitMyDatabaseInfo()
|
||||
* got a correct result. We can't do this until all the
|
||||
* database-access infrastructure is up. (Also, it wants to know if
|
||||
* the user is a superuser, so the above stuff has to happen first.)
|
||||
* Unless we are bootstrapping, double-check that InitMyDatabaseInfo() got
|
||||
* a correct result. We can't do this until all the database-access
|
||||
* infrastructure is up. (Also, it wants to know if the user is a
|
||||
* superuser, so the above stuff has to happen first.)
|
||||
*/
|
||||
if (!bootstrap)
|
||||
ReverifyMyDatabase(dbname);
|
||||
|
||||
/*
|
||||
* Final phase of relation cache startup: write a new cache file if
|
||||
* necessary. This is done after ReverifyMyDatabase to avoid writing
|
||||
* a cache file into a dead database.
|
||||
* necessary. This is done after ReverifyMyDatabase to avoid writing a
|
||||
* cache file into a dead database.
|
||||
*/
|
||||
RelationCacheInitializePhase3();
|
||||
|
||||
@@ -555,8 +554,8 @@ ShutdownPostgres(int code, Datum arg)
|
||||
AbortOutOfAnyTransaction();
|
||||
|
||||
/*
|
||||
* User locks are not released by transaction end, so be sure to
|
||||
* release them explicitly.
|
||||
* User locks are not released by transaction end, so be sure to release
|
||||
* them explicitly.
|
||||
*/
|
||||
#ifdef USER_LOCKS
|
||||
LockReleaseAll(USER_LOCKMETHOD, true);
|
||||
|
||||
Reference in New Issue
Block a user