⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 postmaster.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 5 页
字号:
/*------------------------------------------------------------------------- * * postmaster.c *	  This program acts as a clearing house for requests to the *	  POSTGRES system.	Frontend programs send a startup message *	  to the Postmaster and the postmaster uses the info in the *	  message to setup a backend process. * *	  The postmaster also manages system-wide operations such as *	  startup and shutdown. The postmaster itself doesn't do those *	  operations, mind you --- it just forks off a subprocess to do them *	  at the right times.  It also takes care of resetting the system *	  if a backend crashes. * *	  The postmaster process creates the shared memory and semaphore *	  pools during startup, but as a rule does not touch them itself. *	  In particular, it is not a member of the PGPROC array of backends *	  and so it cannot participate in lock-manager operations.	Keeping *	  the postmaster away from shared memory operations makes it simpler *	  and more reliable.  The postmaster is almost always able to recover *	  from crashes of individual backends by resetting shared memory; *	  if it did much with shared memory then it would be prone to crashing *	  along with the backends. * *	  When a request message is received, we now fork() immediately. *	  The child process performs authentication of the request, and *	  then becomes a backend if successful.  This allows the auth code *	  to be written in a simple single-threaded style (as opposed to the *	  crufty "poor man's multitasking" code that used to be needed). *	  More importantly, it ensures that blockages in non-multithreaded *	  libraries like SSL or PAM cannot cause denial of service to other *	  clients. * * * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION *	  $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.475.2.5 2006/05/19 15:15:38 alvherre Exp $ * * NOTES * * Initialization: *		The Postmaster sets up shared memory data structures *		for the backends. * * Synchronization: *		The Postmaster shares memory with the backends but should avoid *		touching shared memory, so as not to become stuck if a crashing *		backend screws up locks or shared memory.  Likewise, the Postmaster *		should never block on messages from frontend clients. * * Garbage Collection: *		The Postmaster cleans up after backends if they have an emergency *		exit and/or core dump. * * Error Reporting: *		Use write_stderr() only for reporting "interactive" errors *		(essentially, bogus arguments on the command line).  Once the *		postmaster is launched, use ereport().	In particular, don't use *		write_stderr() for anything that occurs after pmdaemonize. * *------------------------------------------------------------------------- */#include "postgres.h"#include <unistd.h>#include <signal.h>#include <time.h>#include <sys/wait.h>#include <ctype.h>#include <sys/stat.h>#include <sys/socket.h>#include <fcntl.h>#include <sys/param.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#include <limits.h>#ifdef HAVE_SYS_SELECT_H#include <sys/select.h>#endif#ifdef HAVE_GETOPT_H#include <getopt.h>#endif#ifdef USE_BONJOUR#include <DNSServiceDiscovery/DNSServiceDiscovery.h>#endif#include "access/xlog.h"#include "bootstrap/bootstrap.h"#include "catalog/pg_control.h"#include "catalog/pg_database.h"#include "commands/async.h"#include "lib/dllist.h"#include "libpq/auth.h"#include "libpq/crypt.h"#include "libpq/libpq.h"#include "libpq/pqcomm.h"#include "libpq/pqsignal.h"#include "miscadmin.h"#include "nodes/nodes.h"#include "pgstat.h"#include "postmaster/autovacuum.h"#include "postmaster/fork_process.h"#include "postmaster/pgarch.h"#include "postmaster/postmaster.h"#include "postmaster/syslogger.h"#include "storage/bufmgr.h"#include "storage/fd.h"#include "storage/ipc.h"#include "storage/pg_shmem.h"#include "storage/pmsignal.h"#include "storage/proc.h"#include "tcop/tcopprot.h"#include "utils/builtins.h"#include "utils/datetime.h"#include "utils/guc.h"#include "utils/memutils.h"#include "utils/ps_status.h"#ifdef EXEC_BACKEND#include "storage/spin.h"#endif/* * List of active backends (or child processes anyway; we don't actually * know whether a given child has become a backend or is still in the * authorization phase).  This is used mainly to keep track of how many * children we have and send them appropriate signals when necessary. * * "Special" children such as the startup and bgwriter tasks are not in * this list. */typedef struct bkend{	pid_t		pid;			/* process id of backend */	long		cancel_key;		/* cancel key for cancels for this backend */} Backend;static Dllist *BackendList;#ifdef EXEC_BACKEND/*  * Number of entries in the backend table. Twice the number of backends, * plus four other subprocesses (stats, bgwriter, autovac, logger).  */#define NUM_BACKENDARRAY_ELEMS (2*MaxBackends + 4)static Backend *ShmemBackendArray;#endif/* The socket number we are listening for connections on */int			PostPortNumber;char	   *UnixSocketDir;char	   *ListenAddresses;/* * ReservedBackends is the number of backends reserved for superuser use. * This number is taken out of the pool size given by MaxBackends so * number of backend slots available to non-superusers is * (MaxBackends - ReservedBackends).  Note what this really means is * "if there are <= ReservedBackends connections available, only superusers * can make new connections" --- pre-existing superuser connections don't * count against the limit. */int			ReservedBackends;/* The socket(s) we're listening to. */#define MAXLISTEN	64static int	ListenSocket[MAXLISTEN];/* * Set by the -o option */static char ExtraOptions[MAXPGPATH];/* * These globals control the behavior of the postmaster in case some * backend dumps core.	Normally, it kills all peers of the dead backend * and reinitializes shared memory.  By specifying -s or -n, we can have * the postmaster stop (rather than kill) peers and not reinitialize * shared data structures. */static bool Reinit = true;static int	SendStop = false;/* still more option variables */bool		EnableSSL = false;bool		SilentMode = false; /* silent mode (-S) */int			PreAuthDelay = 0;int			AuthenticationTimeout = 60;bool		log_hostname;		/* for ps display and logging */bool		Log_connections = false;bool		Db_user_namespace = false;char	   *bonjour_name;/* list of library:init-function to be preloaded */char	   *preload_libraries_string = NULL;/* PIDs of special child processes; 0 when not running */static pid_t StartupPID = 0,			BgWriterPID = 0,			AutoVacPID = 0,			PgArchPID = 0,			PgStatPID = 0,			SysLoggerPID = 0;/* Startup/shutdown state */#define			NoShutdown		0#define			SmartShutdown	1#define			FastShutdown	2static int	Shutdown = NoShutdown;static bool FatalError = false; /* T if recovering from backend crash */bool		ClientAuthInProgress = false;		/* T during new-client												 * authentication *//* * State for assigning random salts and cancel keys. * Also, the global MyCancelKey passes the cancel key assigned to a given * backend from the postmaster to that backend (via fork). */static unsigned int random_seed = 0;extern char *optarg;extern int	optind,			opterr;#ifdef HAVE_INT_OPTRESETextern int	optreset;#endif/* * postmaster.c - function prototypes */static void checkDataDir(void);#ifdef USE_BONJOURstatic void reg_reply(DNSServiceRegistrationReplyErrorType errorCode,		  void *context);#endifstatic void pmdaemonize(void);static Port *ConnCreate(int serverFd);static void ConnFree(Port *port);static void reset_shared(int port);static void SIGHUP_handler(SIGNAL_ARGS);static void pmdie(SIGNAL_ARGS);static void reaper(SIGNAL_ARGS);static void sigusr1_handler(SIGNAL_ARGS);static void dummy_handler(SIGNAL_ARGS);static void CleanupBackend(int pid, int exitstatus);static void HandleChildCrash(int pid, int exitstatus, const char *procname);static void LogChildExit(int lev, const char *procname,			 int pid, int exitstatus);static int	BackendRun(Port *port);static void ExitPostmaster(int status);static void usage(const char *);static int	ServerLoop(void);static int	BackendStartup(Port *port);static int	ProcessStartupPacket(Port *port, bool SSLdone);static void processCancelRequest(Port *port, void *pkt);static int	initMasks(fd_set *rmask);static void report_fork_failure_to_client(Port *port, int errnum);static enum CAC_state canAcceptConnections(void);static long PostmasterRandom(void);static void RandomSalt(char *cryptSalt, char *md5Salt);static void SignalChildren(int signal);static int	CountChildren(void);static bool CreateOptsFile(int argc, char *argv[], char *fullprogname);static pid_t StartChildProcess(int xlop);#ifdef EXEC_BACKEND#ifdef WIN32static void win32_AddChild(pid_t pid, HANDLE handle);static void win32_RemoveChild(pid_t pid);static pid_t win32_waitpid(int *exitstatus);static DWORD WINAPI win32_sigchld_waiter(LPVOID param);static pid_t *win32_childPIDArray;static HANDLE *win32_childHNDArray;static unsigned long win32_numChildren = 0;HANDLE		PostmasterHandle;#endifstatic pid_t backend_forkexec(Port *port);static pid_t internal_forkexec(int argc, char *argv[], Port *port);/* Type for a socket that can be inherited to a client process */#ifdef WIN32typedef struct{	SOCKET		origsocket;		/* Original socket value, or -1 if not a								 * socket */	WSAPROTOCOL_INFO wsainfo;}	InheritableSocket;#elsetypedef int InheritableSocket;#endiftypedef struct LWLock LWLock;	/* ugly kluge *//* * Structure contains all variables passed to exec:ed backends */typedef struct{	Port		port;	InheritableSocket portsocket;	char		DataDir[MAXPGPATH];	int			ListenSocket[MAXLISTEN];	long		MyCancelKey;	unsigned long UsedShmemSegID;	void	   *UsedShmemSegAddr;	slock_t    *ShmemLock;	slock_t    *ShmemIndexLock;	VariableCache ShmemVariableCache;	void	   *ShmemIndexAlloc;	Backend    *ShmemBackendArray;	LWLock	   *LWLockArray;	slock_t    *ProcStructLock;	InheritableSocket pgStatSock;	InheritableSocket pgStatPipe0;	InheritableSocket pgStatPipe1;	pid_t		PostmasterPid;	TimestampTz PgStartTime;#ifdef WIN32	HANDLE		PostmasterHandle;	HANDLE		initial_signal_pipe;	HANDLE		syslogPipe[2];#else	int			syslogPipe[2];#endif	char		my_exec_path[MAXPGPATH];	char		pkglib_path[MAXPGPATH];	char		ExtraOptions[MAXPGPATH];	char		lc_collate[LOCALE_NAME_BUFLEN];	char		lc_ctype[LOCALE_NAME_BUFLEN];}	BackendParameters;static void read_backend_variables(char *id, Port *port);static void restore_backend_variables(BackendParameters * param, Port *port);#ifndef WIN32static bool save_backend_variables(BackendParameters * param, Port *port);#elsestatic bool save_backend_variables(BackendParameters * param, Port *port,					   HANDLE childProcess, pid_t childPid);#endifstatic void ShmemBackendArrayAdd(Backend *bn);static void ShmemBackendArrayRemove(pid_t pid);#endif   /* EXEC_BACKEND */#define StartupDataBase()		StartChildProcess(BS_XLOG_STARTUP)#define StartBackgroundWriter() StartChildProcess(BS_XLOG_BGWRITER)/* * Postmaster main entry point */intPostmasterMain(int argc, char *argv[]){	int			opt;	int			status;	char	   *userDoption = NULL;	int			i;	MyProcPid = PostmasterPid = getpid();	IsPostmasterEnvironment = true;	/*	 * Catch standard options before doing much else.  This even works on	 * systems without getopt_long.	 */	if (argc > 1)	{		if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)		{			usage(progname);			ExitPostmaster(0);		}		if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)		{			puts("postmaster (PostgreSQL) " PG_VERSION);			ExitPostmaster(0);		}	}#ifdef WIN32	/* Start our win32 signal implementation */	pgwin32_signal_initialize();#endif	/*	 * for security, no dir or file created can be group or other accessible	 */	umask((mode_t) 0077);	/*	 * Fire up essential subsystems: memory management	 */	MemoryContextInit();	/*	 * By default, palloc() requests in the postmaster will be allocated in	 * the PostmasterContext, which is space that can be recycled by backends.	 * Allocated data that needs to be available to backends should be	 * allocated in TopMemoryContext.	 */	PostmasterContext = AllocSetContextCreate(TopMemoryContext,											  "Postmaster",											  ALLOCSET_DEFAULT_MINSIZE,											  ALLOCSET_DEFAULT_INITSIZE,											  ALLOCSET_DEFAULT_MAXSIZE);	MemoryContextSwitchTo(PostmasterContext);	IgnoreSystemIndexes(false);	if (find_my_exec(argv[0], my_exec_path) < 0)		elog(FATAL, "%s: could not locate my own executable path",			 argv[0]);	get_pkglib_path(my_exec_path, pkglib_path);	/*	 * Options setup	 */	InitializeGUCOptions();	opterr = 1;	while ((opt = getopt(argc, argv, "A:a:B:b:c:D:d:Fh:ik:lm:MN:no:p:Ss-:")) != -1)	{		switch (opt)		{			case 'A':#ifdef USE_ASSERT_CHECKING				SetConfigOption("debug_assertions", optarg, PGC_POSTMASTER, PGC_S_ARGV);#else				write_stderr("%s: assert checking is not compiled in\n", progname);#endif				break;			case 'a':				/* Can no longer set authentication method. */				break;			case 'B':				SetConfigOption("shared_buffers", optarg, PGC_POSTMASTER, PGC_S_ARGV);				break;			case 'b':				/* Can no longer set the backend executable file to use. */				break;			case 'D':				userDoption = optarg;				break;			case 'd':				set_debug_options(atoi(optarg), PGC_POSTMASTER, PGC_S_ARGV);				break;			case 'F':				SetConfigOption("fsync", "false", PGC_POSTMASTER, PGC_S_ARGV);				break;			case 'h':				SetConfigOption("listen_addresses", optarg, PGC_POSTMASTER, PGC_S_ARGV);				break;			case 'i':				SetConfigOption("listen_addresses", "*", PGC_POSTMASTER, PGC_S_ARGV);				break;			case 'k':				SetConfigOption("unix_socket_directory", optarg, PGC_POSTMASTER, PGC_S_ARGV);				break;#ifdef USE_SSL			case 'l':				SetConfigOption("ssl", "true", PGC_POSTMASTER, PGC_S_ARGV);				break;#endif			case 'm':

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -