aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/init/postinit.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/init/postinit.c')
-rw-r--r--src/backend/utils/init/postinit.c95
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);