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

📄 postmaster.c

📁 PostgreSQL7.4.6 for Linux
💻 C
📖 第 1 页 / 共 5 页
字号:
				 * 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 -- useful only for debugging.				 */				strcat(ExtraOptions, " ");				strcat(ExtraOptions, optarg);				strcpy(original_extraoptions, 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:				fprintf(stderr,					  gettext("Try \"%s --help\" for more information.\n"),						progname);				ExitPostmaster(1);		}	}	/*	 * Postmaster accepts no non-option switch arguments.	 */	if (optind < argc)	{		postmaster_error("invalid argument: \"%s\"", argv[optind]);		fprintf(stderr,				gettext("Try \"%s --help\" for more information.\n"),				progname);		ExitPostmaster(1);	}	/*	 * Now we can set the data directory, and then read postgresql.conf.	 */	checkDataDir(potential_DataDir);	/* issues error messages */	SetDataDir(potential_DataDir);	ProcessConfigFile(PGC_POSTMASTER);#ifdef EXEC_BACKEND	write_nondefault_variables(PGC_POSTMASTER);#endif	/*	 * 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.		 */		postmaster_error("the number of buffers (-B) must be at least twice the number of allowed connections (-N) and at least 16");		ExitPostmaster(1);	}	if (ReservedBackends >= MaxBackends)	{		postmaster_error("superuser_reserved_connections must be less than max_connections");		ExitPostmaster(1);	}	/*	 * Other one-time internal sanity checks can go here.	 */	if (!CheckDateTokenTables())	{		postmaster_error("invalid datetoken tables, please fix");		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("-----------------------------------------")));	}	/*	 * On some systems our dynloader code needs the executable's pathname.	 */	if (FindExec(pg_pathname, progname, "postgres") < 0)		ereport(FATAL,				(errmsg("%s: could not locate postgres executable",						progname)));	/*	 * Initialize SSL library, if specified.	 */#ifdef USE_SSL	if (EnableSSL && !NetServer)	{		postmaster_error("TCP/IP connections must be enabled for SSL");		ExitPostmaster(1);	}	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);	/*	 * 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(argc, argv);	/*	 * 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 before	 * the Unix socket.	 */	CreateDataDirLockFile(DataDir, true);	/*	 * 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 (NetServer)	{		if (VirtualHost && VirtualHost[0])		{			char	   *curhost,					   *endptr;			char		c = 0;			curhost = VirtualHost;			for (;;)			{				while (*curhost == ' ') /* skip any extra spaces */					curhost++;				if (*curhost == '\0')					break;				endptr = strchr(curhost, ' ');				if (endptr)				{					c = *endptr;					*endptr = '\0';				}				status = StreamServerPort(AF_UNSPEC, curhost,										  (unsigned short) PostPortNumber,										  UnixSocketDir,										  ListenSocket, MAXLISTEN);				if (status != STATUS_OK)					ereport(FATAL,					 (errmsg("could not create listen socket for \"%s\"",							 curhost)));				if (endptr)				{					*endptr = c;					curhost = endptr + 1;				}				else					break;			}		}		else		{			status = StreamServerPort(AF_UNSPEC, NULL,									  (unsigned short) PostPortNumber,									  UnixSocketDir,									  ListenSocket, MAXLISTEN);			if (status != STATUS_OK)				ereport(FATAL,					  (errmsg("could not create TCP/IP listen socket")));		}#ifdef USE_RENDEZVOUS		if (rendezvous_name != NULL)		{			DNSServiceRegistrationCreate(rendezvous_name,										 "_postgresql._tcp.",										 "",										 htonl(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(FATAL,				(errmsg("could not create Unix-domain socket")));#endif	XLOGPathInit();	/*	 * 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();	/*	 * Record postmaster options.  We delay this till now to avoid	 * recording bogus options (eg, NBuffers too high for available	 * memory).	 */	if (!CreateOptsFile(argc, argv))		ExitPostmaster(1);	/*	 * 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, and postmaster/pgstat.c.	 */	pqinitmask();	PG_SETMASK(&BlockSig);	pqsignal(SIGHUP, SIGHUP_handler);	/* reread config file and have										 * children do same */	pqsignal(SIGINT, pmdie);	/* send SIGTERM and ShutdownDataBase */	pqsignal(SIGQUIT, pmdie);	/* send SIGQUIT and die */	pqsignal(SIGTERM, pmdie);	/* wait for children and ShutdownDataBase */	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	/*	 * Reset whereToSendOutput from Debug (its starting state) to None.	 * This prevents ereport from sending log messages to stderr unless	 * the syslog/stderr switch permits.  We don't do this until the	 * postmaster is fully launched, since startup failures may as well be	 * reported to stderr.	 */	whereToSendOutput = None;	/*	 * On many platforms, the first call of localtime() incurs significant	 * overhead to load timezone info from the system configuration files.	 * By doing it once in the postmaster, we avoid having to do it in	 * every started child process.  The savings are not huge, but they	 * add up...	 */	{		time_t		now = time(NULL);		(void) localtime(&now);	}	/*	 * Initialize and try to startup the statistics collector process	 */	pgstat_init();	pgstat_start();	/*	 * Load cached files for client authentication.	 */	load_hba();	load_ident();	load_user();	load_group();	/*	 * We're ready to rock and roll...	 */	StartupPID = StartupDataBase();	status = ServerLoop();	/*	 * ServerLoop probably shouldn't ever return, but if it does, close	 * down.	 */	ExitPostmaster(status != STATUS_OK);	return 0;					/* not reached */}static voidpmdaemonize(int argc, char *argv[]){	int			i;	pid_t		pid;#ifdef LINUX_PROFILE	struct itimerval prof_itimer;#endif#ifdef LINUX_PROFILE	/* see comments in BackendStartup */	getitimer(ITIMER_PROF, &prof_itimer);#endif	pid = fork();	if (pid == (pid_t) -1)	{		postmaster_error("could not fork background process: %s",						 strerror(errno));		ExitPostmaster(1);	}	else if (pid)	{							/* parent */		/* Parent should just exit, without doing any atexit cleanup */		_exit(0);	}#ifdef LINUX_PROFILE	setitimer(ITIMER_PROF, &prof_itimer, NULL);#endif	MyProcPid = getpid();		/* reset MyProcPid to child *//* GH: If there's no setsid(), we hopefully don't need silent mode. * Until there's a better solution. */#ifdef HAVE_SETSID	if (setsid() < 0)	{		postmaster_error("could not dissociate from controlling TTY: %s",						 strerror(errno));		ExitPostmaster(1);	}#endif	i = open(NULL_DEV, O_RDWR | PG_BINARY);	dup2(i, 0);	dup2(i, 1);	dup2(i, 2);	close(i);}/* * Print out help message */static voidusage(const char *progname){	printf(gettext("%s is the PostgreSQL server.\n\n"), progname);	printf(gettext("Usage:\n  %s [OPTION]...\n\n"), progname);	printf(gettext("Options:\n"));#ifdef USE_ASSERT_CHECKING	printf(gettext("  -A 1|0          enable/disable run-time assert checking\n"));#endif	printf(gettext("  -B NBUFFERS     number of shared buffers\n"));	printf(gettext("  -c NAME=VALUE   set run-time parameter\n"));	printf(gettext("  -d 1-5          debugging level\n"));	printf(gettext("  -D DATADIR      database directory\n"));	printf(gettext("  -F              turn fsync off\n"));	printf(gettext("  -h HOSTNAME     host name or IP address to listen on\n"));	printf(gettext("  -i              enable TCP/IP connections\n"));	printf(gettext("  -k DIRECTORY    Unix-domain socket location\n"));#ifdef USE_SSL	printf(gettext("  -l              enable SSL connections\n"));#endif	printf(gettext("  -N MAX-CONNECT  maximum number of allowed connections\n"));	printf(gettext("  -o OPTIONS      pass \"OPTIONS\" to each server process\n"));	printf(gettext("  -p PORT         port number to listen on\n"));	printf(gettext("  -S              silent mode (start in background without logging output)\n"));	printf(gettext("  --help          show this help, then exit\n"));	printf(gettext("  --version       output version information, then exit\n"));	printf(gettext("\nDeveloper options:\n"));	printf(gettext("  -n              do not reinitialize shared memory after abnormal exit\n"));	printf(gettext("  -s              send SIGSTOP to all backend servers if one dies\n"));	printf(gettext("\nPlease read the documentation for the complete list of run-time\n"				   "configuration settings and how to set them on the command line or in\n"				   "the configuration file.\n\n"				   "Report bugs to <pgsql-bugs@postgresql.org>.\n"));}static intServerLoop(void){	fd_set		readmask;	int			nSockets;	struct timeval now,				later;	struct timezone tz;	int			i;	gettimeofday(&now, &tz);	nSockets = initMasks(&readmask);	for (;;)	{		Port	   *port;

⌨️ 快捷键说明

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