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

📄 postmaster.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 5 页
字号:
				/* Multiplexed backends no longer supported. */				break;			case 'M':				/*				 * ignore this flag.  This may be passed in because the				 * program was run as 'postgres -M' instead of 'postmaster'				 */				break;			case 'N':				/* The max number of backends to start. */				SetConfigOption("max_connections", optarg, PGC_POSTMASTER, PGC_S_ARGV);				break;			case 'n':				/* Don't reinit shared mem after abnormal exit */				Reinit = false;				break;			case 'o':				/*				 * Other options to pass to the backend on the command line				 */				snprintf(ExtraOptions + strlen(ExtraOptions),						 sizeof(ExtraOptions) - strlen(ExtraOptions),						 " %s", optarg);				break;			case 'p':				SetConfigOption("port", optarg, PGC_POSTMASTER, PGC_S_ARGV);				break;			case 'S':				/*				 * Start in 'S'ilent mode (disassociate from controlling tty).				 * You may also think of this as 'S'ysV mode since it's most				 * badly needed on SysV-derived systems like SVR4 and HP-UX.				 */				SetConfigOption("silent_mode", "true", PGC_POSTMASTER, PGC_S_ARGV);				break;			case 's':				/*				 * In the event that some backend dumps core, send SIGSTOP,				 * rather than SIGQUIT, to all its peers.  This lets the wily				 * post_hacker collect core dumps from everyone.				 */				SendStop = true;				break;			case 'c':			case '-':				{					char	   *name,							   *value;					ParseLongOption(optarg, &name, &value);					if (!value)					{						if (opt == '-')							ereport(ERROR,									(errcode(ERRCODE_SYNTAX_ERROR),									 errmsg("--%s requires a value",											optarg)));						else							ereport(ERROR,									(errcode(ERRCODE_SYNTAX_ERROR),									 errmsg("-c %s requires a value",											optarg)));					}					SetConfigOption(name, value, PGC_POSTMASTER, PGC_S_ARGV);					free(name);					if (value)						free(value);					break;				}			default:				write_stderr("Try \"%s --help\" for more information.\n",							 progname);				ExitPostmaster(1);		}	}	/*	 * Postmaster accepts no non-option switch arguments.	 */	if (optind < argc)	{		write_stderr("%s: invalid argument: \"%s\"\n",					 progname, argv[optind]);		write_stderr("Try \"%s --help\" for more information.\n",					 progname);		ExitPostmaster(1);	}#ifdef EXEC_BACKEND	/* Locate executable backend before we change working directory */	if (find_other_exec(argv[0], "postgres", PG_VERSIONSTR,						postgres_exec_path) < 0)		ereport(FATAL,				(errmsg("%s: could not locate matching postgres executable",						progname)));#endif	/*	 * Locate the proper configuration files and data directory, and read	 * postgresql.conf for the first time.	 */	if (!SelectConfigFiles(userDoption, progname))		ExitPostmaster(2);	/* Verify that DataDir looks reasonable */	checkDataDir();	/* And switch working directory into it */	ChangeToDataDir();	/*	 * Check for invalid combinations of GUC settings.	 */	if (NBuffers < 2 * MaxBackends || NBuffers < 16)	{		/*		 * Do not accept -B so small that backends are likely to starve for		 * lack of buffers.  The specific choices here are somewhat arbitrary.		 */		write_stderr("%s: the number of buffers (-B) must be at least twice the number of allowed connections (-N) and at least 16\n", progname);		ExitPostmaster(1);	}	if (ReservedBackends >= MaxBackends)	{		write_stderr("%s: superuser_reserved_connections must be less than max_connections\n", progname);		ExitPostmaster(1);	}	/*	 * Other one-time internal sanity checks can go here, if they are fast.	 * (Put any slow processing further down, after postmaster.pid creation.)	 */	if (!CheckDateTokenTables())	{		write_stderr("%s: invalid datetoken tables, please fix\n", progname);		ExitPostmaster(1);	}	/*	 * Now that we are done processing the postmaster arguments, reset	 * getopt(3) library so that it will work correctly in subprocesses.	 */	optind = 1;#ifdef HAVE_INT_OPTRESET	optreset = 1;				/* some systems need this too */#endif	/* For debugging: display postmaster environment */	{		extern char **environ;		char	  **p;		ereport(DEBUG3,				(errmsg_internal("%s: PostmasterMain: initial environ dump:",								 progname)));		ereport(DEBUG3,			 (errmsg_internal("-----------------------------------------")));		for (p = environ; *p; ++p)			ereport(DEBUG3,					(errmsg_internal("\t%s", *p)));		ereport(DEBUG3,			 (errmsg_internal("-----------------------------------------")));	}	/*	 * Fork away from controlling terminal, if -S specified.	 *	 * Must do this before we grab any interlock files, else the interlocks	 * will show the wrong PID.	 */	if (SilentMode)		pmdaemonize();	/*	 * Create lockfile for data directory.	 *	 * We want to do this before we try to grab the input sockets, because the	 * data directory interlock is more reliable than the socket-file	 * interlock (thanks to whoever decided to put socket files in /tmp :-().	 * For the same reason, it's best to grab the TCP socket(s) before the	 * Unix socket.	 */	CreateDataDirLockFile(true);	/*	 * If timezone is not set, determine what the OS uses.	(In theory this	 * should be done during GUC initialization, but because it can take as	 * much as several seconds, we delay it until after we've created the	 * postmaster.pid file.  This prevents problems with boot scripts that	 * expect the pidfile to appear quickly.)	 */	pg_timezone_initialize();	/*	 * Initialize SSL library, if specified.	 */#ifdef USE_SSL	if (EnableSSL)		secure_initialize();#endif	/*	 * process any libraries that should be preloaded and optionally	 * pre-initialized	 */	if (preload_libraries_string)		process_preload_libraries(preload_libraries_string);	/*	 * Remove old temporary files.	At this point there can be no other	 * Postgres processes running in this directory, so this should be safe.	 */	RemovePgTempFiles();	/*	 * Establish input sockets.	 */	for (i = 0; i < MAXLISTEN; i++)		ListenSocket[i] = -1;	if (ListenAddresses)	{		char	   *rawstring;		List	   *elemlist;		ListCell   *l;		int			success = 0;		/* Need a modifiable copy of ListenAddresses */		rawstring = pstrdup(ListenAddresses);		/* Parse string into list of identifiers */		if (!SplitIdentifierString(rawstring, ',', &elemlist))		{			/* syntax error in list */			ereport(FATAL,					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),					 errmsg("invalid list syntax for \"listen_addresses\"")));		}		foreach(l, elemlist)		{			char	   *curhost = (char *) lfirst(l);			if (strcmp(curhost, "*") == 0)				status = StreamServerPort(AF_UNSPEC, NULL,										  (unsigned short) PostPortNumber,										  UnixSocketDir,										  ListenSocket, MAXLISTEN);			else				status = StreamServerPort(AF_UNSPEC, curhost,										  (unsigned short) PostPortNumber,										  UnixSocketDir,										  ListenSocket, MAXLISTEN);			if (status == STATUS_OK)				success++;			else				ereport(WARNING,						(errmsg("could not create listen socket for \"%s\"",								curhost)));		}		if (!success && list_length(elemlist))			ereport(FATAL,					(errmsg("could not create any TCP/IP sockets")));		list_free(elemlist);		pfree(rawstring);	}#ifdef USE_BONJOUR	/* Register for Bonjour only if we opened TCP socket(s) */	if (ListenSocket[0] != -1 && bonjour_name != NULL)	{		DNSServiceRegistrationCreate(bonjour_name,									 "_postgresql._tcp.",									 "",									 htons(PostPortNumber),									 "",									 (DNSServiceRegistrationReply) reg_reply,									 NULL);	}#endif#ifdef HAVE_UNIX_SOCKETS	status = StreamServerPort(AF_UNIX, NULL,							  (unsigned short) PostPortNumber,							  UnixSocketDir,							  ListenSocket, MAXLISTEN);	if (status != STATUS_OK)		ereport(WARNING,				(errmsg("could not create Unix-domain socket")));#endif	/*	 * check that we have some socket to listen on	 */	if (ListenSocket[0] == -1)		ereport(FATAL,				(errmsg("no socket created for listening")));	/*	 * Set up shared memory and semaphores.	 */	reset_shared(PostPortNumber);	/*	 * Estimate number of openable files.  This must happen after setting up	 * semaphores, because on some platforms semaphores count as open files.	 */	set_max_safe_fds();	/*	 * Initialize the list of active backends.	 */	BackendList = DLNewList();#ifdef WIN32	/*	 * Initialize the child pid/HANDLE arrays for signal handling.	 */	win32_childPIDArray = (pid_t *)		malloc(mul_size(NUM_BACKENDARRAY_ELEMS, sizeof(pid_t)));	win32_childHNDArray = (HANDLE *)		malloc(mul_size(NUM_BACKENDARRAY_ELEMS, sizeof(HANDLE)));	if (!win32_childPIDArray || !win32_childHNDArray)		ereport(FATAL,				(errcode(ERRCODE_OUT_OF_MEMORY),				 errmsg("out of memory")));	/*	 * Set up a handle that child processes can use to check whether the	 * postmaster is still running.	 */	if (DuplicateHandle(GetCurrentProcess(),						GetCurrentProcess(),						GetCurrentProcess(),						&PostmasterHandle,						0,						TRUE,						DUPLICATE_SAME_ACCESS) == 0)		ereport(FATAL,				(errmsg_internal("could not duplicate postmaster handle: error code %d",								 (int) GetLastError())));#endif	/*	 * Record postmaster options.  We delay this till now to avoid recording	 * bogus options (eg, NBuffers too high for available memory).	 */	if (!CreateOptsFile(argc, argv, my_exec_path))		ExitPostmaster(1);#ifdef EXEC_BACKEND	write_nondefault_variables(PGC_POSTMASTER);#endif	/*	 * Write the external PID file if requested	 */	if (external_pid_file)	{		FILE	   *fpidfile = fopen(external_pid_file, "w");		if (fpidfile)		{			fprintf(fpidfile, "%d\n", MyProcPid);			fclose(fpidfile);			/* Should we remove the pid file on postmaster exit? */		}		else			write_stderr("%s: could not write external PID file \"%s\": %s\n",						 progname, external_pid_file, strerror(errno));	}	/*	 * Set up signal handlers for the postmaster process.	 *	 * CAUTION: when changing this list, check for side-effects on the signal	 * handling setup of child processes.  See tcop/postgres.c,	 * bootstrap/bootstrap.c, postmaster/bgwriter.c, postmaster/autovacuum.c,	 * postmaster/pgarch.c, postmaster/pgstat.c, and postmaster/syslogger.c.	 */	pqinitmask();	PG_SETMASK(&BlockSig);	pqsignal(SIGHUP, SIGHUP_handler);	/* reread config file and have										 * children do same */	pqsignal(SIGINT, pmdie);	/* send SIGTERM and shut down */	pqsignal(SIGQUIT, pmdie);	/* send SIGQUIT and die */	pqsignal(SIGTERM, pmdie);	/* wait for children and shut down */	pqsignal(SIGALRM, SIG_IGN); /* ignored */	pqsignal(SIGPIPE, SIG_IGN); /* ignored */	pqsignal(SIGUSR1, sigusr1_handler); /* message from child process */	pqsignal(SIGUSR2, dummy_handler);	/* unused, reserve for children */	pqsignal(SIGCHLD, reaper);	/* handle child termination */	pqsignal(SIGTTIN, SIG_IGN); /* ignored */	pqsignal(SIGTTOU, SIG_IGN); /* ignored */	/* ignore SIGXFSZ, so that ulimit violations work like disk full */#ifdef SIGXFSZ	pqsignal(SIGXFSZ, SIG_IGN); /* ignored */#endif	/*	 * If enabled, start up syslogger collection subprocess	 */	SysLoggerPID = SysLogger_Start();	/*	 * Reset whereToSendOutput from DestDebug (its starting state) to	 * DestNone. This stops ereport from sending log messages to stderr unless	 * Log_destination permits.  We don't do this until the postmaster is	 * fully launched, since startup failures may as well be reported to	 * stderr.	 */	whereToSendOutput = DestNone;	/*	 * Initialize the statistics collector stuff	 */	pgstat_init();	/*	 * Load configuration files for client authentication.	 */	load_hba();	load_ident();	/*	 * We're ready to rock and roll...	 */	StartupPID = StartupDataBase();	/*	 * Remember postmaster startup time	 */	PgStartTime = GetCurrentTimestamp();	/*	 * Initialize the autovacuum daemon	 */	autovac_init();	status = ServerLoop();	/*	 * ServerLoop probably shouldn't ever return, but if it does, close down.	 */	ExitPostmaster(status != STATUS_OK);	return 0;					/* not reached */}/* * Validate the proposed data directory */static voidcheckDataDir(void){	char		path[MAXPGPATH];	FILE	   *fp;	struct stat stat_buf;	Assert(DataDir);	if (stat(DataDir, &stat_buf) != 0)	{		if (errno == ENOENT)			ereport(FATAL,					(errcode_for_file_access(),					 errmsg("data directory \"%s\" does not exist",							DataDir)));		else			ereport(FATAL,					(errcode_for_file_access(),				 errmsg("could not read permissions of directory \"%s\": %m",						DataDir)));	}	/*	 * Check that the directory belongs to my userid; if not, reject.	 *

⌨️ 快捷键说明

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