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 + -
显示快捷键?