summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael P2011-04-14 06:21:14 +0000
committerPavan Deolasee2011-05-24 10:33:26 +0000
commitffd210505e1a331a8c6980a4032178a42e6f797a (patch)
tree06fb1407835f2566d2cf54a8f06d3c0591d4db06
parent169a44eaa6ccca0ada3be43605e6a0c2ca4bd7e9 (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.c26
-rw-r--r--src/gtm/path/path.c62
-rw-r--r--src/gtm/proxy/proxy_main.c26
-rw-r--r--src/include/gtm/path.h5
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