head	1.35;
access;
symbols
	Version_2_1:1.12
	old_buffer_manager:1.5;
locks; strict;
comment	@ * @;


1.35
date	92.08.03.17.42.01;	author mao;	state Exp;
branches;
next	1.34;

1.34
date	92.07.26.17.00.12;	author mer;	state Exp;
branches;
next	1.33;

1.33
date	92.06.17.04.56.00;	author mer;	state Exp;
branches;
next	1.32;

1.32
date	92.06.10.05.16.30;	author mer;	state Exp;
branches;
next	1.31;

1.31
date	92.04.02.19.14.15;	author mer;	state Exp;
branches;
next	1.30;

1.30
date	92.03.07.19.16.06;	author hong;	state Exp;
branches;
next	1.29;

1.29
date	91.11.12.20.20.29;	author mer;	state Exp;
branches;
next	1.28;

1.28
date	91.09.06.12.31.43;	author hong;	state Exp;
branches;
next	1.27;

1.27
date	91.09.04.17.23.21;	author mer;	state Exp;
branches;
next	1.26;

1.26
date	91.08.13.22.02.02;	author mao;	state Exp;
branches;
next	1.25;

1.25
date	91.08.11.16.36.23;	author mer;	state Exp;
branches;
next	1.24;

1.24
date	91.08.01.11.05.48;	author mer;	state Exp;
branches;
next	1.23;

1.23
date	91.07.29.18.41.44;	author mer;	state Exp;
branches;
next	1.22;

1.22
date	91.07.22.22.21.22;	author mao;	state Exp;
branches;
next	1.21;

1.21
date	91.07.09.03.02.29;	author mao;	state Exp;
branches;
next	1.20;

1.20
date	91.07.02.00.19.55;	author mao;	state Exp;
branches;
next	1.19;

1.19
date	91.05.26.23.13.55;	author kemnitz;	state Exp;
branches;
next	1.18;

1.18
date	91.05.22.14.09.38;	author kemnitz;	state Exp;
branches;
next	1.17;

1.17
date	91.04.26.16.53.12;	author hong;	state Exp;
branches;
next	1.16;

1.16
date	91.04.24.21.05.37;	author mao;	state Exp;
branches;
next	1.15;

1.15
date	91.04.24.12.20.35;	author hong;	state Exp;
branches;
next	1.14;

1.14
date	91.04.04.10.42.03;	author mao;	state Exp;
branches;
next	1.13;

1.13
date	91.04.01.13.53.11;	author kemnitz;	state Exp;
branches;
next	1.12;

1.12
date	91.03.05.14.59.02;	author sp;	state Exp;
branches;
next	1.11;

1.11
date	91.02.28.10.55.30;	author mer;	state Exp;
branches;
next	1.10;

1.10
date	91.02.22.09.05.25;	author mer;	state Exp;
branches;
next	1.9;

1.9
date	91.02.20.00.43.47;	author cimarron;	state Exp;
branches;
next	1.8;

1.8
date	91.02.10.18.23.50;	author cimarron;	state Exp;
branches;
next	1.7;

1.7
date	91.01.25.14.00.59;	author hong;	state Exp;
branches;
next	1.6;

1.6
date	91.01.18.22.27.10;	author hong;	state Exp;
branches;
next	1.5;

1.5
date	91.01.09.16.15.46;	author kemnitz;	state Exp;
branches;
next	1.4;

1.4
date	90.10.24.19.59.49;	author cimarron;	state Exp;
branches;
next	1.3;

1.3
date	90.10.12.14.28.21;	author kemnitz;	state Exp;
branches;
next	1.2;

1.2
date	90.10.10.00.42.45;	author cimarron;	state Exp;
branches;
next	1.1;

1.1
date	90.10.05.16.01.44;	author cimarron;	state Exp;
branches;
next	;


desc
@@


1.35
log
@make PostgresIsInitialized visible outside this file.  this is
(unfortunately) necessary to the HeapTupleSatisfies... code in
order to determine visibility of tuples in the case that the
system is just starting up.
@
text
@/* ----------------------------------------------------------------
 *   FILE
 *	postinit.c
 *	
 *   DESCRIPTION
 *	postgres initialization utilities
 *
 *   INTERFACE ROUTINES
 *	InitPostgres()
 *
 *   NOTES
 *	InitializePostgres() is the function called from PostgresMain
 *	which does all non-trival initialization, mainly by calling
 *	all the other initialization functions.  InitializePostgres()
 *	is only used within the "postgres" backend and so that routine
 *	is in tcop/postgres.c  InitPostgres() is needed in cinterface.a
 *	because things like the bootstrap backend program need it. Hence
 *	you find that in this file...
 *
 *	If you feel the need to add more initialization code, it should be
 *	done in InitializePostgres() or someplace lower.  Do not start
 *	putting stuff in PostgresMain - if you do then someone
 *	will have to clean it up later, and it's not going to be me!
 *	-cim 10/3/90
 *
 *   IDENTIFICATION
 *	$Header: /private/mao/postgres/src/utils/init/RCS/postinit.c,v 1.34 1992/07/26 17:00:12 mer Exp mao $
 * ----------------------------------------------------------------
 */

#include <fcntl.h>
#include <stdio.h>
#include <strings.h>
#include <sys/file.h>
#include <sys/types.h>
#include <math.h>

#include "tmp/postgres.h"

#include "machine.h"		/* for BLCKSZ, for InitMyDatabaseId() */

#include "access/heapam.h"
#include "access/tqual.h"
#include "storage/bufpage.h"	/* for page layout, for InitMyDatabaseId() */
#include "storage/sinval.h"
#include "storage/sinvaladt.h"
#include "storage/lmgr.h"
#include "storage/bufmgr.h"
#include "support/master.h"

#include "tmp/miscadmin.h"
#include "tmp/portal.h"		/* for EnablePortalManager, etc. */

#include "utils/exc.h"		/* for EnableExceptionHandling, etc. */
#include "utils/fmgr.h"		/* for EnableDynamicFunctionManager, etc. */
#include "utils/log.h"
#include "utils/mcxt.h"		/* for EnableMemoryContext, etc. */

#include "catalog/catname.h"
#include "catalog/pg_database.h"

#include "tmp/miscadmin.h"

/* ----------------
 *	global variables & stuff
 *	XXX clean this up! -cim 10/5/90
 * ----------------
 */
    
extern bool	override;
extern int	Quiet;
IPCKey		PostgresIpcKey;

/*
 * XXX PostgresPath and PostgresDatabase belong somewhere else.
 */
String	PostgresPath = NULL;
String	PostgresDatabase = NULL;

extern int Debugfile, Ttyfile;
extern int Portfd, Packfd, Pipefd;

extern BackendId	MyBackendId;
extern BackendTag	MyBackendTag;
extern NameData		MyDatabaseNameData;
extern Name		MyDatabaseName;

extern bool		MyDatabaseIdIsInitialized;
extern ObjectId		MyDatabaseId;
extern bool		TransactionInitWasProcessed;

/* extern struct	bcommon	Ident;	No longer needed */

extern int	Debug_file, Err_file, Noversion;

extern int on_exitpg();

#ifndef	private
#ifndef	EBUG
#define	private	static
#else	/* !defined(EBUG) */
#define private
#endif	/* !defined(EBUG) */
#endif	/* !defined(private) */

/* ----------------------------------------------------------------
 *			InitPostgres support
 * ----------------------------------------------------------------
 */

/* --------------------------------
 *  InitMyDatabaseId() -- Find and record the OID of the database we are
 *			  to open.
 *
 *	The database's oid forms half of the unique key for the system
 *	caches and lock tables.  We therefore want it initialized before
 *	we open any relations, since opening relations puts things in the
 *	cache.  To get around this problem, this code opens and scans the
 *	pg_database relation by hand.
 *
 *	This algorithm relies on the fact that first attribute in the
 *	pg_database relation schema is the database name.  It also knows
 *	about the internal format of tuples on disk and the length of
 *	the datname attribute.  It knows the location of the pg_database
 *	file.
 *
 *	This code is called from InitDatabase(), after we chdir() to the
 *	database directory but before we open any relations.
 * --------------------------------
 */

void
InitMyDatabaseId()
{
    int		dbfd;
    int		nbytes;
    int		max, i;
    HeapTuple	tup;
    Page	pg;
    PageHeader	ph;
    Form_pg_database	tup_db;

    /* ----------------
     *  If we're unable to open pg_database, we're not running in the
     *  data/base/dbname directory.  This happens only when we're
     *  creating the first database.  In that case, just use
     *  InvalidObjectId as the dbid, since we're not using shared memory.
     * ----------------
     */
    if ((dbfd = open("../../pg_database", O_RDONLY, 0666)) < 0) {
	LockDisable(true);
	return;
    }

    /* ----------------
     *	read and examine every page in pg_database
     *
     *	Raw I/O! Read those tuples the hard way! Yow!
     *
     *  Why don't we use the access methods or move this code
     *  someplace else?  This is really pg_database schema dependent
     *  code.  Perhaps it should go in lib/catalog/pg_database?
     *  -cim 10/3/90
     *
     *  mao replies 4 apr 91:  yeah, maybe this should be moved to
     *  lib/catalog.  however, we CANNOT use the access methods since
     *  those use the buffer cache, which uses the relation cache, which
     *  requires that the dbid be set, which is what we're trying to do
     *  here.
     * ----------------
     */
    pg = (Page) palloc(BLCKSZ);
    ph = (PageHeader) pg;

    while ((nbytes = read(dbfd, pg, BLCKSZ)) == BLCKSZ) {
	max = PageGetMaxOffsetIndex(pg);

	/* look at each tuple on the page */
	for (i = 0; i <= max; i++) {
	    int offset;

	    /* if it's a freed tuple, ignore it */
	    if (!(ph->pd_linp[i].lp_flags & LP_USED))
		continue;

	    /* get a pointer to the tuple itself */
	    offset = (int) ph->pd_linp[i].lp_off;
	    tup = (HeapTuple) (((char *) pg) + offset);

	    /*
	     *  if the tuple has been deleted (the database was destroyed),
	     *  skip this tuple.  XXX warning, will robinson:  violation of
	     *  transaction semantics happens right here.  we should check
	     *  to be sure that the xact that deleted this tuple actually
	     *  committed.  only way to do this at init time is to paw over
	     *  the log relation by hand, too.  let's be optimistic.
	     *
	     *  XXX This is an evil type cast.  tup->t_xmax is char[5] while
	     *  TransactionId is struct * { char data[5] }.  It works but
	     *  if data is ever moved and no longer the first field this 
	     *  will be broken!! -mer 11 Nov 1991.
	     */
	    if (TransactionIdIsValid((TransactionId)tup->t_xmax))
		continue;

	    /*
	     *  Okay, see if this is the one we want.
	     *	XXX 1 july 91:  mao and mer discover that tuples now squash
	     *			t_bits.  Why is this?
	     *
	     *     24 july 92:  mer realizes that the t_bits field is only
	     *                  used in the event of null values.  If no
	     *                  fields are null we reduce the header size
	     *                  by doing the squash.  t_hoff tells you exactly
	     *                  how big the header actually is. use the PC
	     *                  means of getting at sys cat attrs.
	     */
	    tup_db = (Form_pg_database)GETSTRUCT(tup);

	    /* note: MyDatabaseName set by call to SetDatabaseName() */
	    if (strncmp(&(MyDatabaseName->data[0]),
			&(tup_db->datname.data[0]),
			16) == 0)
	    {
		MyDatabaseId = tup->t_oid;
		goto done;
	    }
	}
    }
    
done:
    (void) close(dbfd);
    pfree(pg);

    if (!ObjectIdIsValid(MyDatabaseId))
	elog(FATAL,
	     "Database %s does not exist in %s",
	     MyDatabaseName,
	     &DatabaseRelationName->data[0]);
}

/* ----------------
 *	DoChdirAndInitDatabaseNameAndPath
 *
 *	this just chdir's to the proper data/base directory
 *	XXX clean this up more.
 *
 * XXX The following code is an incorrect of the semantics
 * XXX described in the header file.  Handling of defaults
 * XXX should happen here, too.
 * ----------------
 */
void
DoChdirAndInitDatabaseNameAndPath(name, path)
    String	name;		/* name of database */
    String	path;		/* full path to database */
{
    /* ----------------
     *	sanity check (database may not change once set)
     * ----------------
     */
    AssertState(!StringIsValid(GetDatabasePath()));
    AssertState(!StringIsValid(GetDatabaseName()));

    /* ----------------
     *	check the path
     * ----------------
     */
    if (StringIsValid(path))
	SetDatabasePath(path);
    else
	elog(FATAL, "DoChdirAndInitDatabaseNameAndPath: path:%s is not valid",
	     path);

    /* ----------------
     *	check the name
     * ----------------
     */
    if (StringIsValid(name))
	SetDatabaseName(name);
    else 
	elog(FATAL, "DoChdirAndInitDatabaseNameAndPath: name:%s is not valid",
	     name);

    /* ----------------
     *	change to the directory, or die trying.
     * ----------------
     */
    if (chdir(path) < 0)
	elog(FATAL, "DoChdirAndInitDatabaseNameAndPath: chdir(\"%s\"): %m",
	     path);
}

/* --------------------------------
 *	InitUserid
 *
 *	initializes crap associated with the user id.
 * --------------------------------
 */
void
InitUserid() {
    setuid(geteuid());
    SetUserId();
}

/* --------------------------------
 *	InitCommunication
 *
 *	This routine initializes stuff needed for ipc, locking, etc.
 *	it should be called something more informative.
 *
 * Note:
 *	This does not set MyBackendId.  MyBackendTag is set, however.
 * --------------------------------
 */

void
InitCommunication()
{
    String	getenv();	/* XXX style */
    String	postid;
    String	postport;
    IPCKey	key;

    /* ----------------
     *	try and get the backend tag from POSTID
     * ----------------
     */
    MyBackendId = -1;

    postid = getenv("POSTID");
    if (!PointerIsValid(postid)) {
	MyBackendTag = -1;
    } else {
	MyBackendTag = atoi(postid);
	Assert(MyBackendTag >= 0);
    }

    /* ----------------
     *  try and get the ipc key from POSTPORT
     * ----------------
     */
    postport = getenv("POSTPORT");
    
    if (PointerIsValid(postport)) {
	SystemPortAddress address = atoi(postport);

	if (address == 0)
	    elog(FATAL, "InitCommunication: invalid POSTPORT");

	if (MyBackendTag == -1)
	    elog(FATAL, "InitCommunication: missing POSTID");

	key = SystemPortAddressCreateIPCKey(address);

/*
 * Enable this if you are trying to force the backend to run as if it is
 * running under the postmaster.
 *
 * This goto forces Postgres to attach to shared memory instead of using
 * malloc'ed memory (which is the normal behavior if run directly).
 *
 * To enable emulation, run the following shell commands (in addition
 * to enabling this goto)
 *
 *     % setenv POSTID 1
 *     % setenv POSTPORT 4321
 *     % postmaster &
 *     % kill -9 %1
 *
 * Upon doing this, Postmaster will have allocated the shared memory resources
 * that Postgres will attach to if you enable EMULATE_UNDER_POSTMASTER.
 *
 * This comment may well age with time - it is current as of 8 January 1990
 * 
 * Greg
 */

#ifdef EMULATE_UNDER_POSTMASTER

	goto forcesharedmemory;

#endif

    } else if (IsUnderPostmaster) {
	elog(FATAL,
	     "InitCommunication: under postmaster and POSTPORT not set");
    } else {
	/* ----------------
	 *  assume we're running a postgres backend by itself with
	 *  no front end or postmaster.
	 * ----------------
	 */
	if (MyBackendTag == -1) {
	    MyBackendTag = 1;
	}

	key = PrivateIPCKey;
    }

    /* ----------------
     *  initialize shared memory and semaphores appropriately.
     * ----------------
     */
#ifdef EMULATE_UNDER_POSTMASTER

forcesharedmemory:

#endif

    PostgresIpcKey = key;
    AttachSharedMemoryAndSemaphores(key);
}


/* --------------------------------
 *	InitStdio
 *
 *	this routine consists of a bunch of code fragments
 *	that used to be randomly scattered through cinit().
 *	they all seem to do stuff associated with io.
 * --------------------------------
 */
void
InitStdio()
{
    /* ----------------
     *	this appears to be a funky variable used with the IN and OUT
     *  macros for controlling the error message indent level.
     * ----------------
     */
    ElogDebugIndentLevel = 0;

    /* ----------------
     *	old socket initialization crud starts here
     * ----------------
     */
    Ttyfile = 0;
    Debugfile = Debug_file = DebugFileOpen();

    if (IsUnderPostmaster) {
	struct	dpacket	pack;
	    
	/* ----------------
	 *	why the hell are we doing this here???  -cim 
	 * ----------------
	 */
	if (!ValidPgVersion(".") || !ValidPgVersion("../.."))
	{
		extern char *DBName;
	    elog(NOTICE, "InitStdio: !ValidPgVersion");
	    if (strcmp(DBName, "template1"))
	        elog(FATAL, "Did you run createdb on %s yet??", DBName);
	    else
	        elog(FATAL, "Did you run initdb yet??");
	}
    }

    Err_file = ErrorFileOpen();
}

/* --------------------------------
 *	InitPostgres
 *
 * Note:
 *	Be very careful with the order of calls in the InitPostgres function.
 * --------------------------------
 */
bool	PostgresIsInitialized = false;
extern int NBuffers;

/*
 *  this global is used by wei for testing his code, but must be declared
 *  here rather than in postgres.c so that it's defined for cinterface.a
 *  applications.
 */

int	testFlag = 0;
int	lockingOff = 0;

/*
 */
void
InitPostgres(name)
    String	name;		/* database name */
{
    bool	bootstrap;	/* true if BootstrapProcessing */
	extern	DestroyLocalRelList();

    /* ----------------
     *	see if we're running in BootstrapProcessing mode
     * ----------------
     */
    bootstrap = IsBootstrapProcessingMode();
    
    /* ----------------
     *	turn on the exception handler.  Note: we cannot use elog, Assert,
     *  AssertState, etc. until after exception handling is on.
     * ----------------
     */
    EnableExceptionHandling(true);

    /* ----------------
     *	A stupid check to make sure we don't call this more than once.
     *  But things like ReinitPostgres() get around this by just diddling
     *	the PostgresIsInitialized flag.
     * ----------------
     */
    AssertState(!PostgresIsInitialized);

    /* ----------------
     *	EnableTrace is poorly understood by the current postgres
     *  implementation people.  Since none of us know how it really
     *  is intended to function, we keep it turned off for now.
     *  Turning it on will cause a core dump in all the non-sequent
     *  ports.  Actually it may fail there too.  Who knows. -cim 10/3/90
     * ----------------
     */
    EnableTrace(false);

    /* ----------------
     *	Memory system initialization.
     *  (we may call palloc after EnableMemoryContext())
     *
     *  Note EnableMemoryContext() must happen before EnablePortalManager().
     * ----------------
     */
    EnableMemoryContext(true);	/* initializes the "top context" */
    EnablePortalManager(true);	/* memory for portal/transaction stuff */

    /* ----------------
     *	initialize the backend local portal stack used by
     *  internal PQ function calls.  see src/lib/libpq/be-dumpdata.c
     *  This is different from the "portal manager" so this goes here.
     *  -cim 2/12/91
     * ----------------
     */    
    be_portalinit();

    /* ----------------
     *	 attach to shared memory and semaphores, and initialize our
     *   input/output/debugging file descriptors.
     * ----------------
     */
    InitCommunication();
    InitStdio();

    if (!TransactionFlushEnabled())
        on_exitpg(FlushBufferPool, (caddr_t) 0);

    /* ----------------
     *	check for valid "meta gunk" (??? -cim 10/5/90) and change to
     *  database directory.
     *
     *  Note:  DatabaseName, MyDatabaseName, and DatabasePath are all
     *  initialized with DatabaseMetaGunkIsConsistent(), strncpy() and
     *  DoChdirAndInitDatabase() below!  XXX clean this crap up!
     *  -cim 10/5/90
     * ----------------
     */
    {
	static char  myPath[MAXPGPATH];	/* DatabasePath points here! */
	static char  myName[17]; 	/* DatabaseName points here! */

	/* ----------------
	 *  DatabaseMetaGunkIsConsistent fills in myPath, but what about
	 *  when bootstrap or Noversion is true?? -cim 10/5/90
	 * ----------------
	 */
	myPath[0] = '\0';
	
	if (! bootstrap)
	    if (! DatabaseMetaGunkIsConsistent(name, myPath))
		if (! Noversion)
		    elog(FATAL,
			 "InitPostgres: ! DatabaseMetaGunkIsConsistent");
	
	(void) strncpy(myName, name, sizeof(myName));

	/* ----------------
	 *  ok, we've figured out myName and myPath, now save these
	 *  and chdir to myPath.
	 * ----------------
	 */
	DoChdirAndInitDatabaseNameAndPath(myName, myPath);
    }
    
    /* ********************************
     *	code after this point assumes we are in the proper directory!
     * ********************************
     */
    
    /* ----------------
     *	initialize the database id used for system caches and lock tables
     * ----------------
     */
    InitMyDatabaseId();

    smgrinit();

    /* ----------------
     *	initialize the transaction system and the relation descriptor
     *  cache.  Note we have to make certain the lock manager is off while
     *  we do this.
     * ----------------
     */
    AmiTransactionOverride(IsBootstrapProcessingMode());
    LockDisable(true);

    /*
     * Part of the initialization processing done here sets a read
     * lock on pg_log.  Since locking is disabled the set doesn't have
     * intended effect of locking out writers, but this is ok, since
     * we only lock it to examine AMI transaction status, and this is
     * never written after initdb is done. -mer 15 June 1992
     */
    RelationInitialize();	   /* pre-allocated reldescs created here */
    InitializeTransactionSystem(); /* pg_log,etc init/crash recovery here */
    
    LockDisable(false);

    /* ----------------
     *	anyone knows what this does?  something having to do with
     *  system catalog cache invalidation in the case of multiple
     *  backends, I think -cim 10/3/90
     *  Sets up MyBackendId a unique backend identifier.
     * ----------------
     */
    InitSharedInvalidationState();

    /* ----------------
     * Set up a per backend process in shared memory.  Must be done after
     * InitSharedInvalidationState() as it relies on MyBackendId being
     * initialized already.  XXX -mer 11 Aug 1991
     * ----------------
     */
    InitProcess(PostgresIpcKey);

    if (MyBackendId > MaxBackendId || MyBackendId <= 0) {
	elog(FATAL, "cinit2: bad backend id %d (%d)",
	     MyBackendTag,
	     MyBackendId);
    }

    /* ----------------
     *  initialize the access methods and set the heap-randomization
     *  behaviour  (if POSTGROWS is set  then we disable the usual
     *  random-search for a free page when we do an insertion).
     * ----------------
     */
    initam();
    InitRandom();		/* XXX move this to initam() */

    /* ----------------
     *	initialize all the system catalog caches.
     * ----------------
     */
    zerocaches();
    InitCatalogCache();

    /* ----------------
     *   set ourselves to the proper user id and figure out our postgres
     *   user id.  If we ever add security so that we check for valid
     *   postgres users, we might do it here.
     * ----------------
     */
    InitUserid();

    /* ----------------
     *	ok, all done, now let's make sure we don't do it again.
     * ----------------
     */
    PostgresIsInitialized = true;
	on_exitpg(DestroyLocalRelList, NULL);

    /* ----------------
     *  Done with "InitPostgres", now change to NormalProcessing unless
     *  we're in BootstrapProcessing mode.
     * ----------------
     */
    if (!bootstrap)
	SetProcessingMode(NormalProcessing);
    if (testFlag || lockingOff)
	LockDisable(true);
}

/* --------------------------------
 *	ReinitPostgres
 *
 *	It is not clear how this routine is supposed to work, or under
 *	what circumstances it should be called.  But hirohama wrote it
 *	for some reason so it's still here.  -cim 10/3/90
 * --------------------------------
 */
void
ReinitPostgres()
{
    /* assumes exception handling initialized at least once before */
    AssertState(PostgresIsInitialized);

    /* reset all modules */

    EnablePortalManager(false);
    EnableMemoryContext(false);

    EnableExceptionHandling(false);
    EnableTrace(false);

    /* now reinitialize */
    PostgresIsInitialized = false;	/* does it matter where this goes? */
    InitPostgres(NULL);	
}


/* ----------------------------------------------------------------
 *		traps to catch calls to obsolete routines
 * ----------------------------------------------------------------
 */
/* ----------------
 *	cinit
 * ----------------
 */
bool
cinit()
{
    fprintf(stderr, "cinit called! eliminate this!!\n");
    AbortPostgres();
}

/* ----------------
 *	cinit2
 * ----------------
 */
bool
cinit2()
{
    fprintf(stderr, "cinit2 called! eliminate this!!\n");
    AbortPostgres();
}
@


1.34
log
@get dbname the PC way (postgresly correct)
@
text
@d27 1
a27 1
 *	$Header: /private/mer/pg/src/utils/init/RCS/postinit.c,v 1.33 1992/06/17 04:56:00 mer Exp mer $
d469 1
a469 1
static bool	PostgresIsInitialized = false;
@


1.33
log
@get rid of an incorrect "historical artifact" and do the right thing instead
@
text
@d27 1
a27 1
 *	$Header: /u/mer/pg/src/utils/init/RCS/postinit.c,v 1.32 1992/06/10 05:16:30 mer Exp mer $
d60 1
a138 1
    char	*tup_db;
d141 1
d210 7
d218 1
a218 1
	    tup_db = ((char *) tup) + sizeof (*tup) - sizeof(tup->t_bits);
d221 4
a224 1
	    if (strncmp(MyDatabaseName, tup_db, 16) == 0) {
@


1.32
log
@nix a lot of old stuff related to debug logging and extraneous file descs
@
text
@d27 1
a27 1
 *	$Header: /u/mer/pg.debug/src/utils/init/RCS/postinit.c,v 1.31 1992/04/02 19:14:15 mer Exp mer $
d224 5
a228 8
    /* ----------------
     *	don't know why this is here -- historical artifact.  --mao 
     * ----------------
     */
    if (ObjectIdIsValid(MyDatabaseId))
	LockDisable(false);
    else
	LockDisable(true);
d599 7
@


1.31
log
@set UserId correctly (via pg_user)
@
text
@d27 1
a27 1
 *	$Header: /users/mer/pg/src/utils/init/RCS/postinit.c,v 1.30 1992/03/07 19:16:06 hong Exp $
d79 1
a79 1
extern int Debugfile, Ttyfile, Dblog, Slog;
a448 27
	
	Slog = SYSLOG_FD;
/*	Packfd = 5; 	Packfd not used see below */
	Dblog = DBLOG_FD;
	Pipefd = 7;
	
/*
 *	Already done after postgres command line args processing
 *
 *	Portfd = 4;
 *	pq_init(Portfd);
 */
	    
/* ---------------------------
 *  It looks like Packfd was used to allow comm. between the postmaster
 *  and the backend, since this never really happens we don't really need
 *  it.... -mer 2/20/91
 * ---------------------------
 *	read(Packfd, (char *)&pack, sizeof(pack));
 *	bcopy(pack.data, (char *)&Ident, sizeof(Ident));
 */
    } 

#ifdef GO_SLOW
    if (!isatty(fileno(stdout)) && !isatty(fileno(stderr))) {
	setbuf(stdout, (char *)NULL);
	setbuf(stderr, (char *)NULL);
a449 1
#endif GO_SLOW
a450 1
    Dblog = dup(Debugfile);
@


1.30
log
@cleaned up buffer flushing interface
@
text
@d27 1
a27 1
 *	$Header: RCS/postinit.c,v 1.29 91/11/12 20:20:29 mer Exp $
a561 8
     *   set ourselves to the proper user id and figure out our postgres
     *   user id.  If we ever add security so that we check for valid
     *   postgres users, we might do it here.
     * ----------------
     */
    InitUserid();

    /* ----------------
d674 8
@


1.29
log
@prototyping changes
@
text
@d27 1
a27 1
 *	$Header: /users/mer/postgres/src/utils/init/RCS/postinit.c,v 1.28 1991/09/06 12:31:43 hong Exp mer $
d48 1
a95 1
extern void BufferManagerFlush();
d578 1
a578 1
        on_exitpg(BufferManagerFlush, (caddr_t) 0);
@


1.28
log
@hashlib.h is now obsoleted.
@
text
@d27 1
a27 1
 *	$Header: RCS/postinit.c,v 1.27 91/09/04 17:23:21 mer Exp Locker: hong $
d196 5
d202 1
a202 1
	    if (TransactionIdIsValid(tup->t_xmax))
@


1.27
log
@oops - EMULATE_UNDER_POSTMASTER was defined..... shouldn't be.
@
text
@d27 1
a27 1
 *	$Header: RCS/postinit.c,v 1.26 91/08/13 22:02:02 mao Exp Locker: mer $
a49 1
#include "tmp/hasht.h"		/* for EnableHashTable, etc. */
d541 1
a541 2
     *  Note EnableMemoryContext() must happen before EnableHashTable() or
     *  EnablePortalManager().
a544 1
    EnableHashTable(true);	/* memory for hash table sets */
a712 1
    EnableHashTable(false);
@


1.26
log
@change initialization strategy for storage manager -- no longer pass
in IPCKey.
@
text
@d27 1
a27 1
 *	$Header: /local/mao/postgres/src/utils/init/RCS/postinit.c,v 1.25 1991/08/11 16:36:23 mer Exp mao $
a61 2

#define EMULATE_UNDER_POSTMASTER
@


1.25
log
@an error message change and move of InitProcess()
@
text
@d27 1
a27 1
 *	$Header: RCS/postinit.c,v 1.24 91/08/01 11:05:48 mer Exp $
d628 1
a628 7
    /* ----------------
     *  intialize the storage manager switch -- must be after shared memory,
     *  semaphores, and database name get initialized.  PostgresIpcKey gets
     *  set in InitCommunication(), above.
     * ----------------
     */
    smgrinit(PostgresIpcKey);
@


1.24
log
@cleanup lmgr.h include
@
text
@d27 1
a27 1
 *	$Header: utils/init/RCS/postinit.c,v 1.23 91/07/29 18:41:44 mer Exp Locker: mer $
d63 2
d442 4
a445 1
	    elog(FATAL, "Did you run createdb on %s yet??", DBName);
d654 1
d658 8
@


1.23
log
@cleanup LockingIsDisabled
@
text
@d27 1
a27 1
 *	$Header: RCS/postinit.c,v 1.22 91/07/22 22:21:22 mao Exp Locker: mer $
d47 1
a55 1
#include "utils/lmgr.h"
@


1.22
log
@jukebox storage manager installation
@
text
@d27 1
a27 1
 *	$Header: /users/mao/postgres/src/utils/init/RCS/postinit.c,v 1.21 1991/07/09 03:02:29 mao Exp mao $
d151 1
a151 1
	LockingIsDisabled = true;
d225 1
a225 1
	LockingIsDisabled = false;
d227 1
a227 1
	LockingIsDisabled = true;
d638 1
a638 1
    LockingIsDisabled = true;
d643 1
a643 1
    LockingIsDisabled = false;
d690 1
a690 1
	LockingIsDisabled = true;
@


1.21
log
@init storage manager
@
text
@d27 1
a27 1
 *	$Header: /users/mao/postgres/src/utils/init/RCS/postinit.c,v 1.20 1991/07/02 00:19:55 mao Exp mao $
d69 3
a71 2
extern bool override;
extern int Quiet;
d399 1
a556 6
     *  intialize the storage manager switch
     * ----------------
     */
    smgrinit();

    /* ----------------
d622 9
a630 1
    
@


1.20
log
@fix initialization of MyDatabaseId
@
text
@d27 1
a27 1
 *	$Header: /users/mao/postgres/src/utils/init/RCS/postinit.c,v 1.19 1991/05/26 23:13:55 kemnitz Exp mao $
d553 6
@


1.19
log
@added DestroyLocalRelList to on_exitpg.
@
text
@d27 1
a27 1
 *	$Header: RCS/postinit.c,v 1.18 91/05/22 14:09:38 kemnitz Exp Locker: kemnitz $
d200 6
a205 2
	    /* okay, see if this is the one we want */
	    tup_db = ((char *) tup) + sizeof (*tup);
@


1.18
log
@got rid of old btrees.
@
text
@d27 1
a27 1
 *	$Header: RCS/postinit.c,v 1.17 91/04/26 16:53:12 hong Exp Locker: kemnitz $
d496 1
d666 1
@


1.17
log
@to support command line option to turn of locking
@
text
@d27 1
a27 1
 *	$Header: RCS/postinit.c,v 1.16 91/04/24 21:05:37 mao Exp Locker: hong $
a478 1
extern int *BTreeBufferPinCount;
a564 6
    /* 
     * have to allocate the following variable size array for the
     * btree code.  should have been encapsulated. XXX
     */
    BTreeBufferPinCount = (int*)malloc((NBuffers + 1) * sizeof(int));
    
@


1.16
log
@declare wei's testFlag global here, rather than in postgres.c, so it's
defined for cinterface applications.
@
text
@d27 1
a27 1
 *	$Header: RCS/postinit.c,v 1.15 91/04/24 12:20:35 hong Exp Locker: mao $
d488 1
d680 1
a680 1
    if (testFlag)
@


1.15
log
@added a line of special code for my experiments, no affect to anyone else.
@
text
@d27 1
a27 1
 *	$Header: RCS/postinit.c,v 1.14 91/04/04 10:42:03 mao Exp $
d482 3
d486 5
a495 1
    extern int	testFlag;
@


1.14
log
@be sure you get the right dbid at init time -- if a db is destroyed and
then recreated, used to get the old oid.
@
text
@d27 1
a27 1
 *	$Header: RCS/postinit.c,v 1.13 91/04/01 13:53:11 kemnitz Exp Locker: mao $
d488 1
d672 2
@


1.13
log
@Made error message slightly less cryptic.
@
text
@d27 1
a27 1
 *	$Header: RCS/postinit.c,v 1.12 91/03/05 14:59:02 sp Exp Locker: kemnitz $
d163 6
d188 13
a202 1
	    /* see if this is the one we want */
@


1.12
log
@Removed the code that made postgres go (even) slower than normal
if you were unlucky enough to redirect is stdout *and* stderr to a
file...
@
text
@d27 1
a27 1
 *	$Header: RCS/postinit.c,v 1.11 91/02/28 10:55:30 mer Exp Locker: sp $
d413 5
a417 1
	    elog(FATAL, "InitStdio: !ValidPgVersion");
@


1.11
log
@cleaned up System / Error log file initialization
@
text
@d27 1
a27 1
 *	$Header: RCS/postinit.c,v 1.10 91/02/22 09:05:25 mer Exp Locker: mer $
d437 1
d442 1
@


1.10
log
@made modifications for new postmaster

@
text
@d27 1
a27 1
 *	$Header: RCS/postinit.c,v 1.9 91/02/20 00:43:47 cimarron Exp Locker: mer $
d79 1
a79 1
extern int Portfd, Packfd, Slog, Pipefd;
d415 1
a415 2
	Slog = Err_file = SYSLOG_FD;
	Portfd = 4;
d420 6
a425 1
	pq_init(Portfd);
d443 1
a443 1
    Slog = Err_file = ErrorFileOpen();
@


1.9
log
@added call to be_portalinit()
@
text
@d27 1
a27 1
 *	$Header: RCS/postinit.c,v 1.8 91/02/10 18:23:50 cimarron Exp Locker: cimarron $
d90 1
a90 1
extern struct	bcommon	Ident;	/* moved to dlog */
d415 1
a415 1
	Slog = Err_file = 3;
d417 2
a418 2
	Packfd = 5;
	Dblog = 6;
d423 8
a430 2
	read(Packfd, (char *)&pack, sizeof(pack));
	bcopy(pack.data, (char *)&Ident, sizeof(Ident));
@


1.8
log
@reorganization of libpq routines to provide
 PQexec and PQfn functionality from both the front
 end applications and the postgres backend.
@
text
@d27 1
a27 1
 *	$Header: RCS/postinit.c,v 1.7 91/01/25 14:00:59 hong Exp Locker: cimarron $
d497 9
@


1.7
log
@have to allocate some variable size arrays at init time now that we
have variable size buffer pool
@
text
@d27 1
a27 1
 *	$Header: RCS/postinit.c,v 1.6 91/01/18 22:27:10 hong Exp Locker: hong $
d421 1
a421 1
	pinit();
@


1.6
log
@change for the new buffer manager
@
text
@d27 1
a27 1
 *	$Header: RCS/postinit.c,v 1.5 91/01/09 16:15:46 kemnitz Exp Locker: hong $
d444 2
d514 3
a516 12
    /* ----------------
     *	 initialize the buffer manager.  this must happen after
     *   shared memory/semaphore initialization.
     *
     *   if stable main memory is assumed (-S flag is set), it is necessary
     *   to flush all dirty shared buffers before exit (plai 8/7/90) so we
     *   register an on_exitpg() handler also.  This has to be done *after*
     *   InitCommunication or the shared memory will be removed before
     *   BufferManagerFlush will be called, because on_exitpg() handlers are
     *   called in the reverse of the order in which they are registered.
    BufferManagerInit();
     * ----------------
d518 1
@


1.5
log
@Added an ifdef to force Postgres to use shared memory so we can run
it under DBX in essentially the same state as it is in when we are running

the Postmaster.  This is so that bugs like the Ultrix Rule Bug can be fixed
more easily.

@
text
@d27 1
a27 1
 *	$Header: RCS/postinit.c,v 1.4 90/10/24 19:59:49 cimarron Exp Locker: hong $
d522 1
a524 1
    BufferManagerInit();
@


1.4
log
@corrected arguments to InitPostgres()
@
text
@d27 1
a27 1
 *	$Header: RCS/postinit.c,v 1.3 90/10/12 14:28:21 kemnitz Exp Locker: cimarron $
d321 29
d370 6
@


1.3
log
@Added a dummy argument to InitPostgres.
@
text
@d27 1
a27 1
 *	$Header: RCS/postinit.c,v 1.2 90/10/10 00:42:45 cimarron Exp Locker: kemnitz $
d413 1
a413 2
InitPostgres(dummy, name)
	Pointer	dummy;
@


1.2
log
@moved functions around to eliminate linking problem with support/backend.
@
text
@d27 1
a27 1
 *	$Header: RCS/postinit.c,v 1.1 90/10/05 16:01:44 cimarron Exp $
d413 2
a414 1
InitPostgres(name)
@


1.1
log
@
	Main postgres initialization code collected from:

/users/cimarron/postgres14/src/tcop/postgres.c
/users/cimarron/postgres14/src/utils/init/cinit.c
/users/cimarron/postgres14/src/utils/init/pdir.c
/users/cimarron/postgres14/src/utils/init/pinit.c
/users/cimarron/postgres14/src/utils/init/pmod.c
/users/cimarron/postgres14/src/utils/init/pusr.c

	Cim
@
text
@d6 1
a6 1
 *	main postgres initialization routines
a8 1
 *	InitializePostgres()
a9 1
 *	ReinitPostgres()
d14 8
a21 3
 *	all the other initialization functions.   If you feel the
 *	need to add more initialization code, it should be done
 *	in InitializePostgres() or someplace lower.  Do not start
d27 1
a27 1
 *	$Header$
a72 9
 * EnableAbortEnvVarName --
 *	Enables system abort iff set to a non-empty string in environment.
 */
#define EnableAbortEnvVarName	"POSTGRESABORT"

typedef String	EnvVarName;
extern String getenv ARGS((EnvVarName name));

/*
a105 63
 *		some of the 19 ways to leave postgres
 * ----------------------------------------------------------------
 */

/* ----------------
 *	ExitPostgres
 * ----------------
 */
void
ExitPostgres(status)
    ExitStatus	status;
{
#ifdef	__SABER__
    saber_stop();
#endif
    exitpg(status);
}

/* ----------------
 *	AbortPostgres
 * ----------------
 */
void
AbortPostgres()
{
    String abortValue = getenv(EnableAbortEnvVarName);

#ifdef	__SABER__
    saber_stop();
#endif

    if (PointerIsValid(abortValue) && abortValue[0] != '\0')
	abort();
    else
	exitpg(FatalExitStatus);
}

/* ----------------
 *	StatusBackendExit
 * ----------------
 */
void
StatusBackendExit(status)
    int	status;
{
    /* someday, do some real cleanup and then call the LISP exit */
    /* someday, call StatusPostmasterExit if running without postmaster */
    exitpg(status);
}

/* ----------------
 *	StatusPostmasterExit
 * ----------------
 */
void
StatusPostmasterExit(status)
    int	status;
{
    /* someday, do some real cleanup and then call the LISP exit */
    exitpg(status);
}

/* ----------------------------------------------------------------
a628 114
/* ----------------------------------------------------------------
 *	InitializePostgres
 *
 *	This routine should only be called once (by the "master"
 *  	backend).  Put "re-initialization" type stuff someplace else!
 *  	-cim 10/3/90
 * ----------------------------------------------------------------
 */
bool InitializePostgresCalled = false;

void
InitializePostgres(DatabaseName)
    String    DatabaseName;	/* name of database to use */
{
    /* ----------------
     *	sanity checks
     *
     *  Note: we can't call elog yet..
     * ----------------
     */
    if (InitializePostgresCalled) {
	fprintf(stderr, "InitializePostgresCalled more than once!\n");
	exitpg(1);
    } else
	InitializePostgresCalled = true;

    /* ----------------
     *	set processing mode appropriately depending on weather or
     *  not we want the transaction system running.  When the
     *  transaction system is not running, all transactions are
     *  assumed to have successfully committed and we never go to
     *  the transaction log.
     *
     *  The way things seem to work: we start in InitProcessing and
     *  change to NormalProcessing after InitPostgres() is done.  But
     *  if we run with the wierd override flag, then it means we always
     *  run in "BootstrapProcessing" mode.
     *
     * XXX the -C version flag should be removed and combined with -O
     * ----------------
     */
    SetProcessingMode((override) ? BootstrapProcessing : InitProcessing);

    /* ----------------
     *	if fmgr() is called and the desired function is not
     *  in the builtin table, then we call the desired function using
     *  the routine registered in EnableDynamicFunctionManager().
     *  That routine (fmgr_dynamic) is expected to dynamically
     *  load the desired function and then call it.
     *
     *  dynamic loading only works after EnableDynamicFunctionManager()
     *  is called.
     *
     *  XXX Why can't this go in InitPostgres?? -cim 10/5/90
     * ----------------
     */
    if (! Quiet)
	puts("\tEnableDynamicFunctionManager()..");
    EnableDynamicFunctionManager(fmgr_dynamic);
        	
    /* ----------------
     *	initialize portal file descriptors
     *
     *  XXX Why can't this go in InitPostgres?? -cim 10/5/90
     * ----------------
     */
    if (IsUnderPostmaster == true) {
	if (Portfd < 0) {
	    fprintf(stderr,
		    "Postmaster flag set, but no port number specified\n");
	    exitpg(1);
	}
	pinit();
    }
    
    /* ****************************************************
     *	InitPostgres()
     *
     *  Do all the general initialization.  Anything that can be
     *  done more than once should go in InitPostgres().
     * ****************************************************
     */
    if (! Quiet)
	puts("\tInitPostgres()..");
    InitPostgres(DatabaseName);

    /* ----------------
     *  Initialize the Master/Slave shared memory allocator,
     *	fork and initialize the parallel slave backends, and
     *  register the Master semaphore/shared memory cleanup
     *  procedures.
     *
     *  This may *NOT* happen more than once so we can't
     *  put this in InitPostgres() -cim 10/5/90
     * ----------------
     */
    if (ParallelExecutorEnabled()) {
	extern void IPCPrivateSemaphoreKill();
	extern void IPCPrivateMemoryKill();
	
	if (! Quiet)
	    puts("\tInitializing Executor Shared Memory...");
	ExecSMInit();
	
	if (! Quiet)
	    puts("\tInitializing Slave Backends...");
	SlaveBackendsInit();

	if (! Quiet)
	    puts("\tRegistering Master IPC Cleanup Procedures...");
	ExecSemaphoreOnExit(IPCPrivateSemaphoreKill);
	ExecSharedMemoryOnExit(IPCPrivateMemoryKill);
    }
}
@
