diff options
Diffstat (limited to 'src/backend/utils/init/postinit.c')
-rw-r--r-- | src/backend/utils/init/postinit.c | 95 |
1 files changed, 80 insertions, 15 deletions
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c index 8429af83bbe..8fdb3be75e2 100644 --- a/src/backend/utils/init/postinit.c +++ b/src/backend/utils/init/postinit.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.173 2007/01/05 22:19:44 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.174 2007/02/15 23:23:23 alvherre Exp $ * * *------------------------------------------------------------------------- @@ -47,6 +47,7 @@ static bool FindMyDatabase(const char *name, Oid *db_id, Oid *db_tablespace); +static bool FindMyDatabaseByOid(Oid dbid, char *dbname, Oid *db_tablespace); static void CheckMyDatabase(const char *name, bool am_superuser); static void InitCommunication(void); static void ShutdownPostgres(int code, Datum arg); @@ -103,6 +104,48 @@ FindMyDatabase(const char *name, Oid *db_id, Oid *db_tablespace) } /* + * FindMyDatabaseByOid + * + * As above, but the actual database Id is known. Return its name and the + * tablespace OID. Return TRUE if found, FALSE if not. The same restrictions + * as FindMyDatabase apply. + */ +static bool +FindMyDatabaseByOid(Oid dbid, char *dbname, Oid *db_tablespace) +{ + bool result = false; + char *filename; + FILE *db_file; + Oid db_id; + char thisname[NAMEDATALEN]; + TransactionId db_frozenxid; + + filename = database_getflatfilename(); + db_file = AllocateFile(filename, "r"); + if (db_file == NULL) + ereport(FATAL, + (errcode_for_file_access(), + errmsg("could not open file \"%s\": %m", filename))); + + while (read_pg_database_line(db_file, thisname, &db_id, + db_tablespace, &db_frozenxid)) + { + if (dbid == db_id) + { + result = true; + strlcpy(dbname, thisname, NAMEDATALEN); + break; + } + } + + FreeFile(db_file); + pfree(filename); + + return result; +} + + +/* * CheckMyDatabase -- fetch information from the pg_database entry for our DB */ static void @@ -135,9 +178,9 @@ CheckMyDatabase(const char *name, bool am_superuser) * a way to recover from disabling all access to all databases, for * example "UPDATE pg_database SET datallowconn = false;". * - * We do not enforce them for the autovacuum process either. + * We do not enforce them for the autovacuum worker processes either. */ - if (IsUnderPostmaster && !IsAutoVacuumProcess()) + if (IsUnderPostmaster && !IsAutoVacuumWorkerProcess()) { /* * Check that the database is currently allowing connections. @@ -270,8 +313,11 @@ BaseInit(void) * InitPostgres * Initialize POSTGRES. * - * In bootstrap mode neither of the parameters are used. In autovacuum - * mode, the username parameter is not used. + * The database can be specified by name, using the in_dbname parameter, or by + * OID, using the dboid parameter. In the latter case, the computed database + * name is passed out to the caller as a palloc'ed string in out_dbname. + * + * In bootstrap mode no parameters are used. * * The return value indicates whether the userID is a superuser. (That * can only be tested inside a transaction, so we want to do it during @@ -285,12 +331,14 @@ BaseInit(void) * -------------------------------- */ bool -InitPostgres(const char *dbname, const char *username) +InitPostgres(const char *in_dbname, Oid dboid, const char *username, + char **out_dbname) { bool bootstrap = IsBootstrapProcessingMode(); - bool autovacuum = IsAutoVacuumProcess(); + bool autovacuum = IsAutoVacuumWorkerProcess(); bool am_superuser; char *fullpath; + char dbname[NAMEDATALEN]; /* * Set up the global variables holding database id and path. But note we @@ -307,15 +355,32 @@ InitPostgres(const char *dbname, const char *username) else { /* - * Find oid and tablespace of the database we're about to open. Since - * we're not yet up and running we have to use the hackish - * FindMyDatabase, which looks in the flat-file copy of pg_database. + * Find tablespace of the database we're about to open. Since we're not + * yet up and running we have to use one of the hackish FindMyDatabase + * variants, which look in the flat-file copy of pg_database. + * + * If the in_dbname param is NULL, lookup database by OID. */ - if (!FindMyDatabase(dbname, &MyDatabaseId, &MyDatabaseTableSpace)) - ereport(FATAL, - (errcode(ERRCODE_UNDEFINED_DATABASE), - errmsg("database \"%s\" does not exist", - dbname))); + if (in_dbname == NULL) + { + if (!FindMyDatabaseByOid(dboid, dbname, &MyDatabaseTableSpace)) + ereport(FATAL, + (errcode(ERRCODE_UNDEFINED_DATABASE), + errmsg("database %u does not exist", dboid))); + MyDatabaseId = dboid; + /* pass the database name to the caller */ + *out_dbname = pstrdup(dbname); + } + else + { + if (!FindMyDatabase(in_dbname, &MyDatabaseId, &MyDatabaseTableSpace)) + ereport(FATAL, + (errcode(ERRCODE_UNDEFINED_DATABASE), + errmsg("database \"%s\" does not exist", + in_dbname))); + /* our database name is gotten from the caller */ + strlcpy(dbname, in_dbname, NAMEDATALEN); + } } fullpath = GetDatabasePath(MyDatabaseId, MyDatabaseTableSpace); |