Process options from the startup packed in walsender. Only few options

make sense for walsender, but for example application_name and client_encoding
do. We still don't apply per-role settings from pg_db_role_setting, because
that would require connecting to a database to read the table.

Fujii Masao
This commit is contained in:
Heikki Linnakangas 2010-09-13 09:00:30 +00:00
parent df57a5e898
commit 418039d3af
1 changed files with 87 additions and 58 deletions

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.213 2010/07/06 19:18:58 momjian Exp $
* $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.214 2010/09/13 09:00:30 heikki Exp $
*
*
*-------------------------------------------------------------------------
@ -65,6 +65,7 @@ static void CheckMyDatabase(const char *name, bool am_superuser);
static void InitCommunication(void);
static void ShutdownPostgres(int code, Datum arg);
static bool ThereIsAtLeastOneRole(void);
static void process_startup_options(Port *port, bool am_superuser);
static void process_settings(Oid databaseid, Oid roleid);
@ -476,7 +477,6 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
{
bool bootstrap = IsBootstrapProcessingMode();
bool am_superuser;
GucContext gucctx;
char *fullpath;
char dbname[NAMEDATALEN];
@ -650,21 +650,37 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
errmsg("remaining connection slots are reserved for non-replication superuser connections")));
/*
* If walsender, we're done here --- we don't want to connect to any
* particular database.
* If walsender, we don't want to connect to any particular database.
* Just finish the backend startup by processing any options from the
* startup packet, and we're done.
*/
if (am_walsender)
{
Assert(!bootstrap);
/* must have authenticated as a superuser */
if (!am_superuser)
ereport(FATAL,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to start walsender")));
/* process any options passed in the startup packet */
if (MyProcPort != NULL)
process_startup_options(MyProcPort, am_superuser);
/* Apply PostAuthDelay as soon as we've read all options */
if (PostAuthDelay > 0)
pg_usleep(PostAuthDelay * 1000000L);
/* initialize client encoding */
InitializeClientEncoding();
/* report this backend in the PgBackendStatus array */
pgstat_bestart();
/* close the transaction we started above */
CommitTransactionCommand();
return;
}
@ -811,63 +827,12 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
CheckMyDatabase(dbname, am_superuser);
/*
* Now process any command-line switches that were included in the startup
* packet, if we are in a regular backend. We couldn't do this before
* Now process any command-line switches and any additional GUC variable
* settings passed in the startup packet. We couldn't do this before
* because we didn't know if client is a superuser.
*/
gucctx = am_superuser ? PGC_SUSET : PGC_BACKEND;
if (MyProcPort != NULL &&
MyProcPort->cmdline_options != NULL)
{
/*
* The maximum possible number of commandline arguments that could
* come from MyProcPort->cmdline_options is (strlen + 1) / 2; see
* pg_split_opts().
*/
char **av;
int maxac;
int ac;
maxac = 2 + (strlen(MyProcPort->cmdline_options) + 1) / 2;
av = (char **) palloc(maxac * sizeof(char *));
ac = 0;
av[ac++] = "postgres";
/* Note this mangles MyProcPort->cmdline_options */
pg_split_opts(av, &ac, MyProcPort->cmdline_options);
av[ac] = NULL;
Assert(ac < maxac);
(void) process_postgres_switches(ac, av, gucctx);
}
/*
* Process any additional GUC variable settings passed in startup packet.
* These are handled exactly like command-line variables.
*/
if (MyProcPort != NULL)
{
ListCell *gucopts = list_head(MyProcPort->guc_options);
while (gucopts)
{
char *name;
char *value;
name = lfirst(gucopts);
gucopts = lnext(gucopts);
value = lfirst(gucopts);
gucopts = lnext(gucopts);
SetConfigOption(name, value, gucctx, PGC_S_CLIENT);
}
}
process_startup_options(MyProcPort, am_superuser);
/* Process pg_db_role_setting options */
process_settings(MyDatabaseId, GetSessionUserId());
@ -896,6 +861,70 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
CommitTransactionCommand();
}
/*
* Process any command-line switches and any additional GUC variable
* settings passed in the startup packet.
*/
static void
process_startup_options(Port *port, bool am_superuser)
{
GucContext gucctx;
ListCell *gucopts;
gucctx = am_superuser ? PGC_SUSET : PGC_BACKEND;
/*
* First process any command-line switches that were included in the
* startup packet, if we are in a regular backend.
*/
if (port->cmdline_options != NULL)
{
/*
* The maximum possible number of commandline arguments that could
* come from port->cmdline_options is (strlen + 1) / 2; see
* pg_split_opts().
*/
char **av;
int maxac;
int ac;
maxac = 2 + (strlen(port->cmdline_options) + 1) / 2;
av = (char **) palloc(maxac * sizeof(char *));
ac = 0;
av[ac++] = "postgres";
/* Note this mangles port->cmdline_options */
pg_split_opts(av, &ac, port->cmdline_options);
av[ac] = NULL;
Assert(ac < maxac);
(void) process_postgres_switches(ac, av, gucctx);
}
/*
* Process any additional GUC variable settings passed in startup packet.
* These are handled exactly like command-line variables.
*/
gucopts = list_head(port->guc_options);
while (gucopts)
{
char *name;
char *value;
name = lfirst(gucopts);
gucopts = lnext(gucopts);
value = lfirst(gucopts);
gucopts = lnext(gucopts);
SetConfigOption(name, value, gucctx, PGC_S_CLIENT);
}
}
/*
* Load GUC settings from pg_db_role_setting.
*