This applied patch reorganizes the backend code to more cleanly manage
executable names and backend startup.
--
Bruce Momjian | http://candle.pha.pa.us
pgman@candle.pha.pa.us | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073
Index: src/backend/port/beos/support.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/port/beos/support.c,v
retrieving revision 1.8
diff -c -c -r1.8 support.c
*** src/backend/port/beos/support.c 22 Jul 2003 23:30:38 -0000 1.8
--- src/backend/port/beos/support.c 13 May 2004 22:31:03 -0000
***************
*** 16,22 ****
sem_id beos_shm_sem;
/* Global var containing the postgres path */
! extern char pg_pathname[];
/* Shared library loading doesn't work after fork in beos. The solution is to use an exact
--- 16,22 ----
sem_id beos_shm_sem;
/* Global var containing the postgres path */
! extern char my_exec_path[];
/* Shared library loading doesn't work after fork in beos. The solution is to use an exact
***************
*** 50,56 ****
char Cmd[4000];
/* Build arg list */
! sprintf(Cmd, "%s -beossupportserver %d %d &", pg_pathname, (int) beos_dl_port_in, (int)
beos_dl_port_out);
/* Lauch process */
system(Cmd);
--- 50,56 ----
char Cmd[4000];
/* Build arg list */
! sprintf(Cmd, "%s -beossupportserver %d %d &", my_exec_path, (int) beos_dl_port_in, (int)
beos_dl_port_out);
/* Lauch process */
system(Cmd);
Index: src/backend/port/dynloader/bsdi.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/port/dynloader/bsdi.c,v
retrieving revision 1.23
diff -c -c -r1.23 bsdi.c
*** src/backend/port/dynloader/bsdi.c 29 Nov 2003 19:51:54 -0000 1.23
--- src/backend/port/dynloader/bsdi.c 13 May 2004 22:31:03 -0000
***************
*** 18,24 ****
#include "postgres.h"
#ifndef HAVE_DLOPEN
! extern char pg_pathname[];
void *
pg_dlopen(char *filename)
--- 18,24 ----
#include "postgres.h"
#ifndef HAVE_DLOPEN
! extern char my_exec_path[];
void *
pg_dlopen(char *filename)
***************
*** 31,37 ****
*/
if (!dl_initialized)
{
! if (dld_init(dld_find_executable(pg_pathname)))
return NULL;
/*
--- 31,37 ----
*/
if (!dl_initialized)
{
! if (dld_init(dld_find_executable(my_exec_path)))
return NULL;
/*
Index: src/backend/port/dynloader/linux.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/port/dynloader/linux.c,v
retrieving revision 1.27
diff -c -c -r1.27 linux.c
*** src/backend/port/dynloader/linux.c 29 Nov 2003 19:51:54 -0000 1.27
--- src/backend/port/dynloader/linux.c 13 May 2004 22:31:03 -0000
***************
*** 43,49 ****
*/
if (!dl_initialized)
{
! if (dld_init(dld_find_executable(pg_pathname)))
return NULL;
/*
--- 43,49 ----
*/
if (!dl_initialized)
{
! if (dld_init(dld_find_executable(my_exec_path)))
return NULL;
/*
Index: src/backend/port/dynloader/ultrix4.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/port/dynloader/ultrix4.c,v
retrieving revision 1.19
diff -c -c -r1.19 ultrix4.c
*** src/backend/port/dynloader/ultrix4.c 29 Nov 2003 19:51:54 -0000 1.19
--- src/backend/port/dynloader/ultrix4.c 13 May 2004 22:31:03 -0000
***************
*** 17,23 ****
#include "dl.h"
#include "utils/dynamic_loader.h"
! extern char pg_pathname[];
void *
pg_dlopen(char *filename)
--- 17,23 ----
#include "dl.h"
#include "utils/dynamic_loader.h"
! extern char my_exec_path[];
void *
pg_dlopen(char *filename)
***************
*** 31,37 ****
*/
if (!dl_initialized)
{
! if (!dl_init(pg_pathname))
return NULL;
/*
--- 31,37 ----
*/
if (!dl_initialized)
{
! if (!dl_init(my_exec_path))
return NULL;
/*
Index: src/backend/postmaster/pgstat.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/postmaster/pgstat.c,v
retrieving revision 1.68
diff -c -c -r1.68 pgstat.c
*** src/backend/postmaster/pgstat.c 6 May 2004 19:23:25 -0000 1.68
--- src/backend/postmaster/pgstat.c 13 May 2004 22:31:05 -0000
***************
*** 487,493 ****
/* + the pstat file names, and postgres pathname */
snprintf(pgstatBuf[bufc++],MAXPGPATH,"\"%s\"",pgStat_tmpfname);
snprintf(pgstatBuf[bufc++],MAXPGPATH,"\"%s\"",pgStat_fname);
! snprintf(pgstatBuf[bufc++],MAXPGPATH,"\"%s\"",pg_pathname);
snprintf(pgstatBuf[bufc++],MAXPGPATH,"\"%s\"",DataDir);
/* Add to the arg list */
--- 487,493 ----
/* + the pstat file names, and postgres pathname */
snprintf(pgstatBuf[bufc++],MAXPGPATH,"\"%s\"",pgStat_tmpfname);
snprintf(pgstatBuf[bufc++],MAXPGPATH,"\"%s\"",pgStat_fname);
! snprintf(pgstatBuf[bufc++],MAXPGPATH,"\"%s\"",my_exec_path); /* used? */
snprintf(pgstatBuf[bufc++],MAXPGPATH,"\"%s\"",DataDir);
/* Add to the arg list */
***************
*** 500,508 ****
/* Fire off execv in child */
#ifdef WIN32
! pid = win32_forkexec(pg_pathname,av);
#else
! if ((pid = fork()) == 0 && (execv(pg_pathname,av) == -1))
/* FIXME: [fork/exec] suggestions for what to do here? Can't call elog... */
abort();
#endif
--- 500,508 ----
/* Fire off execv in child */
#ifdef WIN32
! pid = win32_forkexec(my_exec_path, av);
#else
! if ((pid = fork()) == 0 && (execv(my_exec_path, av) == -1))
/* FIXME: [fork/exec] suggestions for what to do here? Can't call elog... */
abort();
#endif
***************
*** 530,538 ****
pgStatPipe[0] = atoi(argv[argc++]);
pgStatPipe[1] = atoi(argv[argc++]);
MaxBackends = atoi(argv[argc++]);
! strncpy(pgStat_tmpfname,argv[argc++],MAXPGPATH);
! strncpy(pgStat_fname, argv[argc++],MAXPGPATH);
! strncpy(pg_pathname, argv[argc++],MAXPGPATH);
DataDir = strdup(argv[argc++]);
read_nondefault_variables();
--- 530,538 ----
pgStatPipe[0] = atoi(argv[argc++]);
pgStatPipe[1] = atoi(argv[argc++]);
MaxBackends = atoi(argv[argc++]);
! StrNCpy(pgStat_tmpfname,argv[argc++],MAXPGPATH);
! StrNCpy(pgStat_fname, argv[argc++],MAXPGPATH);
! StrNCpy(my_exec_path, argv[argc++],MAXPGPATH);
DataDir = strdup(argv[argc++]);
read_nondefault_variables();
Index: src/backend/postmaster/postmaster.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/postmaster/postmaster.c,v
retrieving revision 1.385
diff -c -c -r1.385 postmaster.c
*** src/backend/postmaster/postmaster.c 12 May 2004 13:38:39 -0000 1.385
--- src/backend/postmaster/postmaster.c 13 May 2004 22:31:07 -0000
***************
*** 181,187 ****
/* Used to reduce macros tests */
#ifdef EXEC_BACKEND
const bool ExecBackend = true;
-
#else
const bool ExecBackend = false;
#endif
--- 181,186 ----
***************
*** 286,292 ****
static void RandomSalt(char *cryptSalt, char *md5Salt);
static void SignalChildren(int signal);
static int CountChildren(void);
! static bool CreateOptsFile(int argc, char *argv[]);
NON_EXEC_STATIC void SSDataBaseInit(int xlop);
static pid_t SSDataBase(int xlop);
static void
--- 285,291 ----
static void RandomSalt(char *cryptSalt, char *md5Salt);
static void SignalChildren(int signal);
static int CountChildren(void);
! static bool CreateOptsFile(int argc, char *argv[], char *fullprogname);
NON_EXEC_STATIC void SSDataBaseInit(int xlop);
static pid_t SSDataBase(int xlop);
static void
***************
*** 295,300 ****
--- 294,302 ----
__attribute__((format(printf, 1, 2)));
#ifdef EXEC_BACKEND
+
+ char postgres_exec_path[MAXPGPATH];
+
#ifdef WIN32
pid_t win32_forkexec(const char* path, char *argv[]);
***************
*** 323,329 ****
#define StartBackgroundWriter() SSDataBase(BS_XLOG_BGWRITER)
#define ShutdownDataBase() SSDataBase(BS_XLOG_SHUTDOWN)
-
static void
checkDataDir(const char *checkdir)
{
--- 325,330 ----
***************
*** 692,702 ****
/*
* On some systems our dynloader code needs the executable's pathname.
*/
! if (find_my_exec(pg_pathname, argv[0]) < 0)
ereport(FATAL,
! (errmsg("%s: could not locate postgres executable",
progname)));
/*
* Initialize SSL library, if specified.
*/
--- 693,710 ----
/*
* On some systems our dynloader code needs the executable's pathname.
*/
! if (find_my_exec(my_exec_path, argv[0]) < 0)
ereport(FATAL,
! (errmsg("%s: could not locate my own executable path",
progname)));
+ #ifdef EXEC_BACKEND
+ if (find_other_exec(postgres_exec_path, argv[0], "postgres", PG_VERSIONSTR) < 0)
+ ereport(FATAL,
+ (errmsg("%s: could not locate postgres executable or non-matching version",
+ progname)));
+ #endif
+
/*
* Initialize SSL library, if specified.
*/
***************
*** 852,858 ****
* recording bogus options (eg, NBuffers too high for available
* memory).
*/
! if (!CreateOptsFile(argc, argv))
ExitPostmaster(1);
/*
--- 860,866 ----
* recording bogus options (eg, NBuffers too high for available
* memory).
*/
! if (!CreateOptsFile(argc, argv, my_exec_path))
ExitPostmaster(1);
/*
***************
*** 2754,2763 ****
Assert(ac <= lengthof(av));
#ifdef WIN32
! pid = win32_forkexec(pg_pathname,av); /* logs on error */
#else
/* Fire off execv in child */
! if ((pid = fork()) == 0 && (execv(pg_pathname,av) == -1))
/*
* FIXME: [fork/exec] suggestions for what to do here?
* Probably OK to issue error (unlike pgstat case)
--- 2762,2771 ----
Assert(ac <= lengthof(av));
#ifdef WIN32
! pid = win32_forkexec(postgres_exec_path, av); /* logs on error */
#else
/* Fire off execv in child */
! if ((pid = fork()) == 0 && (execv(postgres_exec_path, av) == -1))
/*
* FIXME: [fork/exec] suggestions for what to do here?
* Probably OK to issue error (unlike pgstat case)
***************
*** 3116,3127 ****
#ifdef EXEC_BACKEND
/* EXEC_BACKEND case; fork/exec here */
#ifdef WIN32
! pid = win32_forkexec(pg_pathname,av); /* logs on error */
#else
! if ((pid = fork()) == 0 && (execv(pg_pathname,av) == -1))
{
/* in child */
! elog(ERROR,"unable to execv in SSDataBase: %m");
exit(0);
}
#endif
--- 3124,3135 ----
#ifdef EXEC_BACKEND
/* EXEC_BACKEND case; fork/exec here */
#ifdef WIN32
! pid = win32_forkexec(postgres_exec_path, av); /* logs on error */
#else
! if ((pid = fork()) == 0 && (execv(postgres_exec_path, av) == -1))
{
/* in child */
! elog(ERROR, "unable to execv in SSDataBase: %m");
exit(0);
}
#endif
***************
*** 3215,3232 ****
* Create the opts file
*/
static bool
! CreateOptsFile(int argc, char *argv[])
{
- char fullprogname[MAXPGPATH];
char filename[MAXPGPATH];
FILE *fp;
int i;
-
- if (find_my_exec(fullprogname, argv[0]) < 0)
- {
- elog(LOG, "could not locate postmaster");
- return false;
- }
snprintf(filename, sizeof(filename), "%s/postmaster.opts", DataDir);
--- 3223,3233 ----
* Create the opts file
*/
static bool
! CreateOptsFile(int argc, char *argv[], char *fullprogname)
{
char filename[MAXPGPATH];
FILE *fp;
int i;
snprintf(filename, sizeof(filename), "%s/postmaster.opts", DataDir);
Index: src/backend/tcop/postgres.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/tcop/postgres.c,v
retrieving revision 1.404
diff -c -c -r1.404 postgres.c
*** src/backend/tcop/postgres.c 12 May 2004 13:38:40 -0000 1.404
--- src/backend/tcop/postgres.c 13 May 2004 22:31:12 -0000
***************
*** 2159,2165 ****
}
if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
{
! puts("postgres (PostgreSQL) " PG_VERSION);
exit(0);
}
}
--- 2159,2165 ----
}
if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
{
! puts(PG_VERSIONSTR);
exit(0);
}
}
***************
*** 2646,2659 ****
}
/*
! * On some systems our dynloader code needs the executable's
! * pathname. (If under postmaster, this was done already.)
*/
! if (find_my_exec(pg_pathname, argv[0]) < 0)
ereport(FATAL,
(errmsg("%s: could not locate postgres executable",
argv[0])));
-
/*
* Validate we have been given a reasonable-looking DataDir (if
* under postmaster, assume postmaster did this already).
--- 2646,2657 ----
}
/*
! * On some systems our dynloader code needs the executable's pathname.
*/
! if (strlen(my_exec_path) == 0 && find_my_exec(my_exec_path, argv[0]) < 0)
ereport(FATAL,
(errmsg("%s: could not locate postgres executable",
argv[0])));
/*
* Validate we have been given a reasonable-looking DataDir (if
* under postmaster, assume postmaster did this already).
Index: src/backend/utils/init/globals.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/utils/init/globals.c,v
retrieving revision 1.84
diff -c -c -r1.84 globals.c
*** src/backend/utils/init/globals.c 10 Feb 2004 03:42:45 -0000 1.84
--- src/backend/utils/init/globals.c 13 May 2004 22:31:12 -0000
***************
*** 45,52 ****
char OutputFileName[MAXPGPATH];
! char pg_pathname[MAXPGPATH]; /* full path to postgres
! * executable */
BackendId MyBackendId;
--- 45,51 ----
char OutputFileName[MAXPGPATH];
! char my_exec_path[MAXPGPATH]; /* full path to postgres executable */
BackendId MyBackendId;
Index: src/include/miscadmin.h
===================================================================
RCS file: /cvsroot/pgsql-server/src/include/miscadmin.h,v
retrieving revision 1.157
diff -c -c -r1.157 miscadmin.h
*** src/include/miscadmin.h 11 May 2004 21:57:15 -0000 1.157
--- src/include/miscadmin.h 13 May 2004 22:31:13 -0000
***************
*** 124,129 ****
--- 124,131 ----
#endif
extern void ClosePostmasterPorts(bool pgstat_too);
+ #define PG_VERSIONSTR "postgres (PostgreSQL) " PG_VERSION "\n"
+
/*
* from utils/init/globals.c
*/
***************
*** 140,146 ****
extern long MyCancelKey;
extern char OutputFileName[];
! extern char pg_pathname[];
/*
* done in storage/backendid.h for now.
--- 142,148 ----
extern long MyCancelKey;
extern char OutputFileName[];
! extern char my_exec_path[];
/*
* done in storage/backendid.h for now.
Index: src/port/exec.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/port/exec.c,v
retrieving revision 1.3
diff -c -c -r1.3 exec.c
*** src/port/exec.c 13 May 2004 01:47:12 -0000 1.3
--- src/port/exec.c 13 May 2004 22:31:14 -0000
***************
*** 184,190 ****
char *path,
*startp,
*endp;
- const char *binary_name = get_progname(argv0);
/*
* First try: use the binary that's located in the
--- 184,189 ----
***************
*** 192,215 ****
* Presumably the user used an explicit path because it
* wasn't in PATH, and we don't want to use incompatible executables.
*
! * This has the neat property that it works for installed binaries, old
! * source trees (obj/support/post{master,gres}) and new source
! * trees (obj/post{master,gres}) because they all put the two binaries
! * in the same place.
! *
! * for the binary: First try: if we're given some kind of path, use it
* (making sure that a relative path is made absolute before returning
* it).
*/
! if (argv0 && (p = last_path_separator(argv0)) && *++p)
{
if (is_absolute_path(argv0) || !getcwd(buf, MAXPGPATH))
buf[0] = '\0';
! else
strcat(buf, "/");
strcat(buf, argv0);
- p = last_path_separator(buf);
- strcpy(++p, binary_name);
if (validate_exec(buf) == 0)
{
strncpy(full_path, buf, MAXPGPATH);
--- 191,213 ----
* Presumably the user used an explicit path because it
* wasn't in PATH, and we don't want to use incompatible executables.
*
! * For the binary: First try: if we're given some kind of path, use it
* (making sure that a relative path is made absolute before returning
* it).
*/
! /* Does argv0 have a separator? */
! if (argv0 && (p = last_path_separator(argv0)))
{
+ if (*++p == '\0')
+ {
+ log_debug("argv[0] ends with a path separator \"%s\"", argv0);
+ return -1;
+ }
if (is_absolute_path(argv0) || !getcwd(buf, MAXPGPATH))
buf[0] = '\0';
! else /* path is not absolute and getcwd worked */
strcat(buf, "/");
strcat(buf, argv0);
if (validate_exec(buf) == 0)
{
strncpy(full_path, buf, MAXPGPATH);
***************
*** 239,249 ****
*endp = '\0';
if (is_absolute_path(startp) || !getcwd(buf, MAXPGPATH))
buf[0] = '\0';
! else
strcat(buf, "/");
strcat(buf, startp);
strcat(buf, "/");
! strcat(buf, binary_name);
switch (validate_exec(buf))
{
case 0: /* found ok */
--- 237,247 ----
*endp = '\0';
if (is_absolute_path(startp) || !getcwd(buf, MAXPGPATH))
buf[0] = '\0';
! else /* path is not absolute and getcwd worked */
strcat(buf, "/");
strcat(buf, startp);
strcat(buf, "/");
! strcat(buf, argv0);
switch (validate_exec(buf))
{
case 0: /* found ok */
***************
*** 265,271 ****
free(path);
}
! log_debug("could not find a \"%s\" to execute", binary_name);
return -1;
}
--- 263,269 ----
free(path);
}
! log_debug("could not find a \"%s\" to execute", argv0);
return -1;
}