diff options
author | Michael P | 2011-04-14 06:21:14 +0000 |
---|---|---|
committer | Pavan Deolasee | 2011-05-24 10:33:26 +0000 |
commit | ffd210505e1a331a8c6980a4032178a42e6f797a (patch) | |
tree | 06fb1407835f2566d2cf54a8f06d3c0591d4db06 | |
parent | 169a44eaa6ccca0ada3be43605e6a0c2ca4bd7e9 (diff) |
Fix for bug 2990360: relative path to working directory for gtm
Fix an issue with GTM path when its binary is called with a relative path
Ex: ./bin/gtm -D data-gtm
This was causing gtm to quit with a FATAL error because it was not able to
find gtm data repository correctly.
Patch written by Benny Wang
-rw-r--r-- | src/gtm/main/main.c | 26 | ||||
-rw-r--r-- | src/gtm/path/path.c | 62 | ||||
-rw-r--r-- | src/gtm/proxy/proxy_main.c | 26 | ||||
-rw-r--r-- | src/include/gtm/path.h | 5 |
4 files changed, 119 insertions, 0 deletions
diff --git a/src/gtm/main/main.c b/src/gtm/main/main.c index 80f35b32ae..9bfa9da475 100644 --- a/src/gtm/main/main.c +++ b/src/gtm/main/main.c @@ -26,6 +26,7 @@ #include "gtm/gtm_c.h" #include "gtm/gtm.h" +#include "gtm/path.h" #include "gtm/elog.h" #include "gtm/memutils.h" #include "gtm/gtm_list.h" @@ -84,6 +85,7 @@ static void GTM_UnregisterPGXCNode(Port *myport, GTM_PGXCNodeId pgxc_node_id); static bool CreateOptsFile(int argc, char *argv[]); static void CreateDataDirLockFile(void); static void CreateLockFile(const char *filename, const char *refName); +static void SetDataDir(void); static void ChangeToDataDir(void); static void checkDataDir(void); static void DeleteLockFile(const char *filename); @@ -143,6 +145,7 @@ BaseInit() MemoryContextInit(); checkDataDir(); + SetDataDir(); ChangeToDataDir(); CreateDataDirLockFile(); @@ -1181,6 +1184,29 @@ retry: } /* + * Set data directory, but make sure it's an absolute path. Use this, + * never set DataDir directly. + */ +void +SetDataDir() +{ + char *new; + + /* If presented path is relative, convert to absolute */ + new = make_absolute_path(GTMDataDir); + if (!new) + ereport(FATAL, + (errno, + errmsg("failed to set the data directory \"%s\"", + GTMDataDir))); + + if (GTMDataDir) + free(GTMDataDir); + + GTMDataDir = new; +} + +/* * Change working directory to DataDir. Most of the postmaster and backend * code assumes that we are in DataDir so it can use relative paths to access * stuff in and under the data directory. For convenience during path diff --git a/src/gtm/path/path.c b/src/gtm/path/path.c index 11c62908ab..4a3298b3d7 100644 --- a/src/gtm/path/path.c +++ b/src/gtm/path/path.c @@ -20,6 +20,7 @@ #include <sys/stat.h> #include <string.h> #include <stdio.h> +#include <unistd.h> #include <gtm/path.h> @@ -175,3 +176,64 @@ trim_trailing_separator(char *path) for (p--; p > path && IS_DIR_SEP(*p); p--) *p = '\0'; } +/* + * If the given pathname isn't already absolute, make it so, interpreting + * it relative to the current working directory. + * + * Also canonicalize the path. The result is always a malloc'd copy. + * + */ +char * +make_absolute_path(const char *path) +{ + char *new; + + /* Returning null for null input is convenient for some callers */ + if (path == NULL) + return NULL; + + if (!is_absolute_path(path)) + { + char *buf; + size_t buflen; + + buflen = MAXPGPATH; + for (;;) + { + buf = malloc(buflen); + if (!buf) + return NULL; + + if (getcwd(buf, buflen)) + break; + else if (errno == ERANGE) + { + free(buf); + buflen *= 2; + continue; + } + else + { + free(buf); + return NULL; + } + } + + new = malloc(strlen(buf) + strlen(path) + 2); + if (!new) + return NULL; + sprintf(new, "%s/%s", buf, path); + free(buf); + } + else + { + new = strdup(path); + if (!new) + return NULL; + } + + /* Make sure punctuation is canonical, too */ + canonicalize_path(new); + + return new; +} diff --git a/src/gtm/proxy/proxy_main.c b/src/gtm/proxy/proxy_main.c index f1e8553dd6..e7632e15d8 100644 --- a/src/gtm/proxy/proxy_main.c +++ b/src/gtm/proxy/proxy_main.c @@ -24,6 +24,7 @@ #include <getopt.h> #include "gtm/gtm_c.h" +#include "gtm/path.h" #include "gtm/gtm_proxy.h" #include "gtm/register.h" #include "gtm/elog.h" @@ -112,6 +113,7 @@ static void GTMProxy_CommandPending(GTMProxy_ConnectionInfo *conninfo, static bool CreateOptsFile(int argc, char *argv[]); static void CreateDataDirLockFile(void); static void CreateLockFile(const char *filename, const char *refName); +static void SetDataDir(void); static void ChangeToDataDir(void); static void checkDataDir(void); static void DeleteLockFile(const char *filename); @@ -174,6 +176,7 @@ BaseInit() MemoryContextInit(); checkDataDir(); + SetDataDir(); ChangeToDataDir(); CreateDataDirLockFile(); @@ -2008,6 +2011,29 @@ retry: } /* + * Set data directory, but make sure it's an absolute path. Use this, + * never set DataDir directly. + */ +void +SetDataDir() +{ + char *new; + + /* If presented path is relative, convert to absolute */ + new = make_absolute_path(GTMProxyDataDir); + if (!new) + ereport(FATAL, + (errno, + errmsg("failed to set the data directory \"%s\"", + GTMProxyDataDir))); + + if (GTMProxyDataDir) + free(GTMProxyDataDir); + + GTMProxyDataDir = new; +} + +/* * Change working directory to DataDir. Most of the postmaster and backend * code assumes that we are in DataDir so it can use relative paths to access * stuff in and under the data directory. For convenience during path diff --git a/src/include/gtm/path.h b/src/include/gtm/path.h index e95ca5e86b..cc07813ace 100644 --- a/src/include/gtm/path.h +++ b/src/include/gtm/path.h @@ -11,6 +11,11 @@ * *------------------------------------------------------------------------- */ +#ifndef _PATH_H +#define _PATH_H + #include "gtm/gtm_c.h" extern void canonicalize_path(char *path); +extern char *make_absolute_path(const char *path); +#endif |