miscinit.c
来自「postgresql8.3.4源码,开源数据库」· C语言 代码 · 共 1,216 行 · 第 1/3 页
C
1,216 行
/*------------------------------------------------------------------------- * * miscinit.c * miscellaneous initialization support stuff * * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION * $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.166 2008/01/03 21:23:15 tgl Exp $ * *------------------------------------------------------------------------- */#include "postgres.h"#include <sys/param.h>#include <signal.h>#include <sys/file.h>#include <sys/stat.h>#include <sys/time.h>#include <fcntl.h>#include <unistd.h>#include <grp.h>#include <pwd.h>#include <netinet/in.h>#include <arpa/inet.h>#ifdef HAVE_UTIME_H#include <utime.h>#endif#include "catalog/pg_authid.h"#include "miscadmin.h"#include "postmaster/autovacuum.h"#include "storage/fd.h"#include "storage/ipc.h"#include "storage/pg_shmem.h"#include "storage/proc.h"#include "storage/procarray.h"#include "utils/builtins.h"#include "utils/guc.h"#include "utils/syscache.h"#define DIRECTORY_LOCK_FILE "postmaster.pid"ProcessingMode Mode = InitProcessing;/* Note: we rely on this to initialize as zeroes */static char socketLockFile[MAXPGPATH];/* ---------------------------------------------------------------- * ignoring system indexes support stuff * * NOTE: "ignoring system indexes" means we do not use the system indexes * for lookups (either in hardwired catalog accesses or in planner-generated * plans). We do, however, still update the indexes when a catalog * modification is made. * ---------------------------------------------------------------- */bool IgnoreSystemIndexes = false;/* ---------------------------------------------------------------- * system index reindexing support * * When we are busy reindexing a system index, this code provides support * for preventing catalog lookups from using that index. * ---------------------------------------------------------------- */static Oid currentlyReindexedHeap = InvalidOid;static Oid currentlyReindexedIndex = InvalidOid;/* * ReindexIsProcessingHeap * True if heap specified by OID is currently being reindexed. */boolReindexIsProcessingHeap(Oid heapOid){ return heapOid == currentlyReindexedHeap;}/* * ReindexIsProcessingIndex * True if index specified by OID is currently being reindexed. */boolReindexIsProcessingIndex(Oid indexOid){ return indexOid == currentlyReindexedIndex;}/* * SetReindexProcessing * Set flag that specified heap/index are being reindexed. */voidSetReindexProcessing(Oid heapOid, Oid indexOid){ Assert(OidIsValid(heapOid) && OidIsValid(indexOid)); /* Reindexing is not re-entrant. */ if (OidIsValid(currentlyReindexedIndex)) elog(ERROR, "cannot reindex while reindexing"); currentlyReindexedHeap = heapOid; currentlyReindexedIndex = indexOid;}/* * ResetReindexProcessing * Unset reindexing status. */voidResetReindexProcessing(void){ currentlyReindexedHeap = InvalidOid; currentlyReindexedIndex = InvalidOid;}/* ---------------------------------------------------------------- * database path / name support stuff * ---------------------------------------------------------------- */voidSetDatabasePath(const char *path){ if (DatabasePath) { free(DatabasePath); DatabasePath = NULL; } /* use strdup since this is done before memory contexts are set up */ if (path) { DatabasePath = strdup(path); AssertState(DatabasePath); }}/* * Set data directory, but make sure it's an absolute path. Use this, * never set DataDir directly. */voidSetDataDir(const char *dir){ char *new; AssertArg(dir); /* If presented path is relative, convert to absolute */ new = make_absolute_path(dir); if (DataDir) free(DataDir); DataDir = new;}/* * Change working directory to DataDir. Most of the postmaster and backend * code assumes that we are in DataDir so it can use relative paths to access * stuff in and under the data directory. For convenience during path * setup, however, we don't force the chdir to occur during SetDataDir. */voidChangeToDataDir(void){ AssertState(DataDir); if (chdir(DataDir) < 0) ereport(FATAL, (errcode_for_file_access(), errmsg("could not change directory to \"%s\": %m", DataDir)));}/* * If the given pathname isn't already absolute, make it so, interpreting * it relative to the current working directory. * * Also canonicalizes the path. The result is always a malloc'd copy. * * Note: interpretation of relative-path arguments during postmaster startup * should happen before doing ChangeToDataDir(), else the user will probably * not like the results. */char *make_absolute_path(const char *path){ char *new; /* Returning null for null input is convenient for some callers */ if (path == NULL) return NULL; if (!is_absolute_path(path)) { char *buf; size_t buflen; buflen = MAXPGPATH; for (;;) { buf = malloc(buflen); if (!buf) ereport(FATAL, (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of memory"))); if (getcwd(buf, buflen)) break; else if (errno == ERANGE) { free(buf); buflen *= 2; continue; } else { free(buf); elog(FATAL, "could not get current working directory: %m"); } } new = malloc(strlen(buf) + strlen(path) + 2); if (!new) ereport(FATAL, (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of memory"))); sprintf(new, "%s/%s", buf, path); free(buf); } else { new = strdup(path); if (!new) ereport(FATAL, (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of memory"))); } /* Make sure punctuation is canonical, too */ canonicalize_path(new); return new;}/* ---------------------------------------------------------------- * User ID state * * We have to track several different values associated with the concept * of "user ID". * * AuthenticatedUserId is determined at connection start and never changes. * * SessionUserId is initially the same as AuthenticatedUserId, but can be * changed by SET SESSION AUTHORIZATION (if AuthenticatedUserIsSuperuser). * This is the ID reported by the SESSION_USER SQL function. * * OuterUserId is the current user ID in effect at the "outer level" (outside * any transaction or function). This is initially the same as SessionUserId, * but can be changed by SET ROLE to any role that SessionUserId is a * member of. (XXX rename to something like CurrentRoleId?) * * CurrentUserId is the current effective user ID; this is the one to use * for all normal permissions-checking purposes. At outer level this will * be the same as OuterUserId, but it changes during calls to SECURITY * DEFINER functions, as well as locally in some specialized commands. * * SecurityDefinerContext is TRUE if we are within a SECURITY DEFINER function * or another context that temporarily changes CurrentUserId. * ---------------------------------------------------------------- */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;static bool SessionUserIsSuperuser = false;static bool SecurityDefinerContext = false;/* We also remember if a SET ROLE is currently active */static bool SetRoleIsActive = false;/* * GetUserId - get the current effective user ID. * * Note: there's no SetUserId() anymore; use SetUserIdAndContext(). */OidGetUserId(void){ AssertState(OidIsValid(CurrentUserId)); return CurrentUserId;}/* * GetOuterUserId/SetOuterUserId - get/set the outer-level user ID. */OidGetOuterUserId(void){ AssertState(OidIsValid(OuterUserId)); return OuterUserId;}static voidSetOuterUserId(Oid userid){ AssertState(!SecurityDefinerContext); AssertArg(OidIsValid(userid)); OuterUserId = userid; /* We force the effective user ID to match, too */ CurrentUserId = userid;}/* * GetSessionUserId/SetSessionUserId - get/set the session user ID. */OidGetSessionUserId(void){ AssertState(OidIsValid(SessionUserId)); return SessionUserId;}static voidSetSessionUserId(Oid userid, bool is_superuser){ AssertState(!SecurityDefinerContext); AssertArg(OidIsValid(userid)); SessionUserId = userid; SessionUserIsSuperuser = is_superuser; SetRoleIsActive = false; /* We force the effective user IDs to match, too */ OuterUserId = userid; CurrentUserId = userid;}/* * GetUserIdAndContext/SetUserIdAndContext - get/set the current user ID * and the SecurityDefinerContext flag. * * Unlike GetUserId, GetUserIdAndContext does *not* Assert that the current * value of CurrentUserId is valid; nor does SetUserIdAndContext require * the new value to be valid. In fact, these routines had better not * ever throw any kind of error. This is because they are used by * StartTransaction and AbortTransaction to save/restore the settings, * and during the first transaction within a backend, the value to be saved * and perhaps restored is indeed invalid. We have to be able to get * through AbortTransaction without asserting in case InitPostgres fails. */voidGetUserIdAndContext(Oid *userid, bool *sec_def_context){ *userid = CurrentUserId; *sec_def_context = SecurityDefinerContext;}voidSetUserIdAndContext(Oid userid, bool sec_def_context){ CurrentUserId = userid; SecurityDefinerContext = sec_def_context;}/* * InSecurityDefinerContext - are we inside a SECURITY DEFINER context? */boolInSecurityDefinerContext(void){ return SecurityDefinerContext;}/* * Initialize user identity during normal backend startup */voidInitializeSessionUserId(const char *rolename){ HeapTuple roleTup; Form_pg_authid rform; Datum datum; bool isnull; Oid roleid; /* * Don't do scans if we're bootstrapping, none of the system catalogs
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?