📄 miscinit.c
字号:
/*------------------------------------------------------------------------- * * miscinit.c * miscellaneous initialization support stuff * * Portions Copyright (c) 1996-2005, 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.150.2.1 2005/11/22 18:23:24 momjian 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 "libpq/libpq-be.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/lsyscache.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. * ---------------------------------------------------------------- */static bool isIgnoringSystemIndexes = false;/* * IsIgnoringSystemIndexes * True if ignoring system indexes. */boolIsIgnoringSystemIndexes(void){ return isIgnoringSystemIndexes;}/* * IgnoreSystemIndexes * Set true or false whether PostgreSQL ignores system indexes. */voidIgnoreSystemIndexes(bool mode){ isIgnoringSystemIndexes = mode;}/* ---------------------------------------------------------------- * 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. We store this mainly so that AtAbort_UserId knows what to * reset CurrentUserId to. * * 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. * ---------------------------------------------------------------- */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;/* We also remember if a SET ROLE is currently active */static bool SetRoleIsActive = false;/* * GetUserId/SetUserId - get/set the current effective user ID. */OidGetUserId(void){ AssertState(OidIsValid(CurrentUserId)); return CurrentUserId;}voidSetUserId(Oid userid){ AssertArg(OidIsValid(userid)); CurrentUserId = userid;}/* * GetOuterUserId/SetOuterUserId - get/set the outer-level user ID. */OidGetOuterUserId(void){ AssertState(OidIsValid(OuterUserId)); return OuterUserId;}static voidSetOuterUserId(Oid userid){ 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){ AssertArg(OidIsValid(userid)); SessionUserId = userid; SessionUserIsSuperuser = is_superuser; SetRoleIsActive = false; /* We force the effective user IDs to match, too */ OuterUserId = userid; CurrentUserId = userid;}/* * 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 * exist yet, and they should be owned by postgres anyway. */ AssertState(!IsBootstrapProcessingMode()); /* call only once */ AssertState(!OidIsValid(AuthenticatedUserId)); roleTup = SearchSysCache(AUTHNAME, PointerGetDatum(rolename), 0, 0, 0); if (!HeapTupleIsValid(roleTup)) ereport(FATAL, (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION), errmsg("role \"%s\" does not exist", rolename)));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -