Commit 6f1b3cf1 authored by Neil Conway's avatar Neil Conway

Use AllocateFile(), FreeFile() and palloc() rather than fopen(), fclose()

and malloc() in pgstat.c, respectively. This simplifies error recovery,
as well as being more consistent with the rest of the backend.
parent e6f9bf9b
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* *
* Copyright (c) 2001-2004, PostgreSQL Global Development Group * Copyright (c) 2001-2004, PostgreSQL Global Development Group
* *
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.83 2004/10/25 06:27:21 neilc Exp $ * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.84 2004/10/28 01:38:41 neilc Exp $
* ---------- * ----------
*/ */
#include "postgres.h" #include "postgres.h"
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include "miscadmin.h" #include "miscadmin.h"
#include "postmaster/postmaster.h" #include "postmaster/postmaster.h"
#include "storage/backendid.h" #include "storage/backendid.h"
#include "storage/fd.h"
#include "storage/ipc.h" #include "storage/ipc.h"
#include "storage/pg_shmem.h" #include "storage/pg_shmem.h"
#include "storage/pmsignal.h" #include "storage/pmsignal.h"
...@@ -682,7 +683,7 @@ pgstat_bestart(void) ...@@ -682,7 +683,7 @@ pgstat_bestart(void)
/* ---------- /* ----------
* pgstat_report_activity() - * pgstat_report_activity() -
* *
* Called in tcop/postgres.c to tell the collector what the backend * Called from tcop/postgres.c to tell the collector what the backend
* is actually doing (usually "<IDLE>" or the start of the query to * is actually doing (usually "<IDLE>" or the start of the query to
* be executed). * be executed).
* ---------- * ----------
...@@ -988,7 +989,7 @@ pgstat_ping(void) ...@@ -988,7 +989,7 @@ pgstat_ping(void)
/* /*
* Create or enlarge the pgStatTabstatMessages array * Create or enlarge the pgStatTabstatMessages array
*/ */
static bool static void
more_tabstat_space(void) more_tabstat_space(void)
{ {
PgStat_MsgTabstat *newMessages; PgStat_MsgTabstat *newMessages;
...@@ -998,39 +999,25 @@ more_tabstat_space(void) ...@@ -998,39 +999,25 @@ more_tabstat_space(void)
/* Create (another) quantum of message buffers */ /* Create (another) quantum of message buffers */
newMessages = (PgStat_MsgTabstat *) newMessages = (PgStat_MsgTabstat *)
malloc(sizeof(PgStat_MsgTabstat) * TABSTAT_QUANTUM); MemoryContextAllocZero(TopMemoryContext,
if (newMessages == NULL) sizeof(PgStat_MsgTabstat) * TABSTAT_QUANTUM);
{
ereport(LOG,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory")));
return false;
}
/* Create or enlarge the pointer array */ /* Create or enlarge the pointer array */
if (pgStatTabstatMessages == NULL) if (pgStatTabstatMessages == NULL)
msgArray = (PgStat_MsgTabstat **) msgArray = (PgStat_MsgTabstat **)
malloc(sizeof(PgStat_MsgTabstat *) * newAlloc); MemoryContextAlloc(TopMemoryContext,
sizeof(PgStat_MsgTabstat *) * newAlloc);
else else
msgArray = (PgStat_MsgTabstat **) msgArray = (PgStat_MsgTabstat **)
realloc(pgStatTabstatMessages, repalloc(pgStatTabstatMessages,
sizeof(PgStat_MsgTabstat *) * newAlloc); sizeof(PgStat_MsgTabstat *) * newAlloc);
if (msgArray == NULL)
{
free(newMessages);
ereport(LOG,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory")));
return false;
}
MemSet(newMessages, 0, sizeof(PgStat_MsgTabstat) * TABSTAT_QUANTUM);
for (i = 0; i < TABSTAT_QUANTUM; i++) for (i = 0; i < TABSTAT_QUANTUM; i++)
msgArray[pgStatTabstatAlloc + i] = newMessages++; msgArray[pgStatTabstatAlloc + i] = newMessages++;
pgStatTabstatMessages = msgArray; pgStatTabstatMessages = msgArray;
pgStatTabstatAlloc = newAlloc; pgStatTabstatAlloc = newAlloc;
return true; Assert(pgStatTabstatUsed < pgStatTabstatAlloc);
} }
/* ---------- /* ----------
...@@ -1102,14 +1089,7 @@ pgstat_initstats(PgStat_Info *stats, Relation rel) ...@@ -1102,14 +1089,7 @@ pgstat_initstats(PgStat_Info *stats, Relation rel)
* If we ran out of message buffers, we just allocate more. * If we ran out of message buffers, we just allocate more.
*/ */
if (pgStatTabstatUsed >= pgStatTabstatAlloc) if (pgStatTabstatUsed >= pgStatTabstatAlloc)
{ more_tabstat_space();
if (!more_tabstat_space())
{
stats->no_stats = TRUE;
return;
}
Assert(pgStatTabstatUsed < pgStatTabstatAlloc);
}
/* /*
* Use the first entry of the next message buffer. * Use the first entry of the next message buffer.
...@@ -1146,10 +1126,8 @@ pgstat_count_xact_commit(void) ...@@ -1146,10 +1126,8 @@ pgstat_count_xact_commit(void)
* new xact-counters. * new xact-counters.
*/ */
if (pgStatTabstatAlloc == 0) if (pgStatTabstatAlloc == 0)
{ more_tabstat_space();
if (!more_tabstat_space())
return;
}
if (pgStatTabstatUsed == 0) if (pgStatTabstatUsed == 0)
{ {
pgStatTabstatUsed++; pgStatTabstatUsed++;
...@@ -1180,10 +1158,8 @@ pgstat_count_xact_rollback(void) ...@@ -1180,10 +1158,8 @@ pgstat_count_xact_rollback(void)
* new xact-counters. * new xact-counters.
*/ */
if (pgStatTabstatAlloc == 0) if (pgStatTabstatAlloc == 0)
{ more_tabstat_space();
if (!more_tabstat_space())
return;
}
if (pgStatTabstatUsed == 0) if (pgStatTabstatUsed == 0)
{ {
pgStatTabstatUsed++; pgStatTabstatUsed++;
...@@ -1529,13 +1505,8 @@ PgstatCollectorMain(int argc, char *argv[]) ...@@ -1529,13 +1505,8 @@ PgstatCollectorMain(int argc, char *argv[])
/* /*
* Create the known backends table * Create the known backends table
*/ */
pgStatBeTable = (PgStat_StatBeEntry *) malloc( pgStatBeTable = (PgStat_StatBeEntry *) palloc0(
sizeof(PgStat_StatBeEntry) * MaxBackends); sizeof(PgStat_StatBeEntry) * MaxBackends);
if (pgStatBeTable == NULL)
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory in statistics collector --- abort")));
memset(pgStatBeTable, 0, sizeof(PgStat_StatBeEntry) * MaxBackends);
readPipe = pgStatPipe[0]; readPipe = pgStatPipe[0];
...@@ -1804,11 +1775,7 @@ pgstat_recvbuffer(void) ...@@ -1804,11 +1775,7 @@ pgstat_recvbuffer(void)
/* /*
* Allocate the message buffer * Allocate the message buffer
*/ */
msgbuffer = (char *) malloc(PGSTAT_RECVBUFFERSZ); msgbuffer = (char *) palloc(PGSTAT_RECVBUFFERSZ);
if (msgbuffer == NULL)
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory in statistics collector --- abort")));
/* /*
* Loop forever * Loop forever
...@@ -2416,7 +2383,7 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb, ...@@ -2416,7 +2383,7 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
* simply return zero for anything and the collector simply starts * simply return zero for anything and the collector simply starts
* from scratch with empty counters. * from scratch with empty counters.
*/ */
if ((fpin = fopen(pgStat_fname, PG_BINARY_R)) == NULL) if ((fpin = AllocateFile(pgStat_fname, PG_BINARY_R)) == NULL)
return; return;
/* /*
...@@ -2437,8 +2404,7 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb, ...@@ -2437,8 +2404,7 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
{ {
ereport(pgStatRunningInCollector ? LOG : WARNING, ereport(pgStatRunningInCollector ? LOG : WARNING,
(errmsg("corrupted pgstat.stat file"))); (errmsg("corrupted pgstat.stat file")));
fclose(fpin); goto done;
return;
} }
/* /*
...@@ -2450,7 +2416,6 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb, ...@@ -2450,7 +2416,6 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
&found); &found);
if (dbentry == NULL) if (dbentry == NULL)
{ {
fclose(fpin);
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY), (errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory"))); errmsg("out of memory")));
...@@ -2459,8 +2424,7 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb, ...@@ -2459,8 +2424,7 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
{ {
ereport(pgStatRunningInCollector ? LOG : WARNING, ereport(pgStatRunningInCollector ? LOG : WARNING,
(errmsg("corrupted pgstat.stat file"))); (errmsg("corrupted pgstat.stat file")));
fclose(fpin); goto done;
return;
} }
memcpy(dbentry, &dbbuf, sizeof(PgStat_StatDBEntry)); memcpy(dbentry, &dbbuf, sizeof(PgStat_StatDBEntry));
...@@ -2479,19 +2443,10 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb, ...@@ -2479,19 +2443,10 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
hash_ctl.entrysize = sizeof(PgStat_StatTabEntry); hash_ctl.entrysize = sizeof(PgStat_StatTabEntry);
hash_ctl.hash = tag_hash; hash_ctl.hash = tag_hash;
hash_ctl.hcxt = use_mcxt; hash_ctl.hcxt = use_mcxt;
PG_TRY(); dbentry->tables = hash_create("Per-database table",
{ PGSTAT_TAB_HASH_SIZE,
dbentry->tables = hash_create("Per-database table", &hash_ctl,
PGSTAT_TAB_HASH_SIZE, HASH_ELEM | HASH_FUNCTION | mcxt_flags);
&hash_ctl,
HASH_ELEM | HASH_FUNCTION | mcxt_flags);
}
PG_CATCH();
{
fclose(fpin);
PG_RE_THROW();
}
PG_END_TRY();
/* /*
* Arrange that following 'T's add entries to this * Arrange that following 'T's add entries to this
...@@ -2515,8 +2470,7 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb, ...@@ -2515,8 +2470,7 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
{ {
ereport(pgStatRunningInCollector ? LOG : WARNING, ereport(pgStatRunningInCollector ? LOG : WARNING,
(errmsg("corrupted pgstat.stat file"))); (errmsg("corrupted pgstat.stat file")));
fclose(fpin); goto done;
return;
} }
/* /*
...@@ -2529,19 +2483,15 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb, ...@@ -2529,19 +2483,15 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
(void *) &tabbuf.tableid, (void *) &tabbuf.tableid,
HASH_ENTER, &found); HASH_ENTER, &found);
if (tabentry == NULL) if (tabentry == NULL)
{
fclose(fpin);
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY), (errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory"))); errmsg("out of memory")));
}
if (found) if (found)
{ {
ereport(pgStatRunningInCollector ? LOG : WARNING, ereport(pgStatRunningInCollector ? LOG : WARNING,
(errmsg("corrupted pgstat.stat file"))); (errmsg("corrupted pgstat.stat file")));
fclose(fpin); goto done;
return;
} }
memcpy(tabentry, &tabbuf, sizeof(tabbuf)); memcpy(tabentry, &tabbuf, sizeof(tabbuf));
...@@ -2552,30 +2502,23 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb, ...@@ -2552,30 +2502,23 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
*/ */
case 'M': case 'M':
if (betab == NULL || numbackends == NULL) if (betab == NULL || numbackends == NULL)
{ goto done;
fclose(fpin);
return;
}
if (fread(&maxbackends, 1, sizeof(maxbackends), fpin) != if (fread(&maxbackends, 1, sizeof(maxbackends), fpin) !=
sizeof(maxbackends)) sizeof(maxbackends))
{ {
ereport(pgStatRunningInCollector ? LOG : WARNING, ereport(pgStatRunningInCollector ? LOG : WARNING,
(errmsg("corrupted pgstat.stat file"))); (errmsg("corrupted pgstat.stat file")));
fclose(fpin); goto done;
return;
} }
if (maxbackends == 0) if (maxbackends == 0)
{ goto done;
fclose(fpin);
return;
}
/* /*
* Allocate space (in TopTransactionContext too) for the * Allocate space (in TopTransactionContext too) for the
* backend table. * backend table.
*/ */
if (use_mcxt == NULL) if (use_mcxt == NULL)
*betab = (PgStat_StatBeEntry *) malloc( *betab = (PgStat_StatBeEntry *) palloc(
sizeof(PgStat_StatBeEntry) * maxbackends); sizeof(PgStat_StatBeEntry) * maxbackends);
else else
*betab = (PgStat_StatBeEntry *) MemoryContextAlloc( *betab = (PgStat_StatBeEntry *) MemoryContextAlloc(
...@@ -2587,16 +2530,8 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb, ...@@ -2587,16 +2530,8 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
* 'B' A PgStat_StatBeEntry follows. * 'B' A PgStat_StatBeEntry follows.
*/ */
case 'B': case 'B':
if (betab == NULL || numbackends == NULL) if (betab == NULL || numbackends == NULL || *betab == NULL)
{ goto done;
fclose(fpin);
return;
}
if (*betab == NULL)
{
fclose(fpin);
return;
}
/* /*
* Read it directly into the table. * Read it directly into the table.
...@@ -2607,8 +2542,7 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb, ...@@ -2607,8 +2542,7 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
{ {
ereport(pgStatRunningInCollector ? LOG : WARNING, ereport(pgStatRunningInCollector ? LOG : WARNING,
(errmsg("corrupted pgstat.stat file"))); (errmsg("corrupted pgstat.stat file")));
fclose(fpin); goto done;
return;
} }
/* /*
...@@ -2624,28 +2558,25 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb, ...@@ -2624,28 +2558,25 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
if (numbackends != 0) if (numbackends != 0)
*numbackends = havebackends; *numbackends = havebackends;
if (havebackends >= maxbackends) if (havebackends >= maxbackends)
{ goto done;
fclose(fpin);
return;
}
break; break;
/* /*
* 'E' The EOF marker of a complete stats file. * 'E' The EOF marker of a complete stats file.
*/ */
case 'E': case 'E':
fclose(fpin); goto done;
return;
default: default:
ereport(pgStatRunningInCollector ? LOG : WARNING, ereport(pgStatRunningInCollector ? LOG : WARNING,
(errmsg("corrupted pgstat.stat file"))); (errmsg("corrupted pgstat.stat file")));
fclose(fpin); goto done;
return;
} }
} }
fclose(fpin); done:
FreeFile(fpin);
} }
/* /*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment