SCRIPT_PREFIX, SCRIPT_EXT);
if ((script = fopen_priv(*analyze_script_file_name, "w")) == NULL)
- pg_fatal("Could not open file \"%s\": %s\n",
- *analyze_script_file_name, getErrorText());
+ pg_fatal("could not open file \"%s\": %s\n",
+ *analyze_script_file_name, strerror(errno));
#ifndef WIN32
/* add shebang header */
#ifndef WIN32
if (chmod(*analyze_script_file_name, S_IRWXU) != 0)
- pg_fatal("Could not add execute permission to file \"%s\": %s\n",
- *analyze_script_file_name, getErrorText());
+ pg_fatal("could not add execute permission to file \"%s\": %s\n",
+ *analyze_script_file_name, strerror(errno));
#endif
termPQExpBuffer(&user_specification);
prep_status("Creating script to delete old cluster");
if ((script = fopen_priv(*deletion_script_file_name, "w")) == NULL)
- pg_fatal("Could not open file \"%s\": %s\n",
- *deletion_script_file_name, getErrorText());
+ pg_fatal("could not open file \"%s\": %s\n",
+ *deletion_script_file_name, strerror(errno));
#ifndef WIN32
/* add shebang header */
#ifndef WIN32
if (chmod(*deletion_script_file_name, S_IRWXU) != 0)
- pg_fatal("Could not add execute permission to file \"%s\": %s\n",
- *deletion_script_file_name, getErrorText());
+ pg_fatal("could not add execute permission to file \"%s\": %s\n",
+ *deletion_script_file_name, strerror(errno));
#endif
check_ok();
{
found = true;
if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
- pg_fatal("Could not open file \"%s\": %s\n",
- output_path, getErrorText());
+ pg_fatal("could not open file \"%s\": %s\n",
+ output_path, strerror(errno));
if (!db_used)
{
fprintf(script, "Database: %s\n", active_db->db_name);
{
found = true;
if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
- pg_fatal("Could not open file \"%s\": %s\n",
- output_path, getErrorText());
+ pg_fatal("could not open file \"%s\": %s\n",
+ output_path, strerror(errno));
if (!db_used)
{
fprintf(script, "Database: %s\n", active_db->db_name);
{
found = true;
if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
- pg_fatal("Could not open file \"%s\": %s\n",
- output_path, getErrorText());
+ pg_fatal("could not open file \"%s\": %s\n",
+ output_path, strerror(errno));
if (!db_used)
{
fprintf(script, "Database: %s\n", active_db->db_name);
if ((output = popen(cmd, "r")) == NULL ||
fgets(cmd_output, sizeof(cmd_output), output) == NULL)
- pg_fatal("Could not get pg_ctl version data using %s: %s\n",
- cmd, getErrorText());
+ pg_fatal("could not get pg_ctl version data using %s: %s\n",
+ cmd, strerror(errno));
pclose(output);
fflush(stderr);
if ((output = popen(cmd, "r")) == NULL)
- pg_fatal("Could not get control data using %s: %s\n",
- cmd, getErrorText());
+ pg_fatal("could not get control data using %s: %s\n",
+ cmd, strerror(errno));
/* Only in <= 9.2 */
if (GET_MAJOR_VERSION(cluster->major_version) <= 902)
/* ENOTDIR means we will throw a more useful error later */
if (errno != ENOENT && errno != ENOTDIR)
pg_fatal("could not open file \"%s\" for reading: %s\n",
- path, getErrorText());
+ path, strerror(errno));
return false;
}
if (stat(subDirName, &statBuf) != 0)
report_status(PG_FATAL, "check for \"%s\" failed: %s\n",
- subDirName, getErrorText());
+ subDirName, strerror(errno));
else if (!S_ISDIR(statBuf.st_mode))
report_status(PG_FATAL, "%s is not a directory\n",
subDirName);
/* check bindir */
if (stat(cluster->bindir, &statBuf) != 0)
report_status(PG_FATAL, "check for \"%s\" failed: %s\n",
- cluster->bindir, getErrorText());
+ cluster->bindir, strerror(errno));
else if (!S_ISDIR(statBuf.st_mode))
report_status(PG_FATAL, "%s is not a directory\n",
cluster->bindir);
*/
if (stat(path, &buf) < 0)
pg_fatal("check for \"%s\" failed: %s\n",
- path, getErrorText());
+ path, strerror(errno));
else if (!S_ISREG(buf.st_mode))
pg_fatal("check for \"%s\" failed: not an executable file\n",
path);
#include <fcntl.h>
-#ifndef WIN32
-static int copy_file(const char *fromfile, const char *tofile);
-#else
+#ifdef WIN32
static int win32_pghardlink(const char *src, const char *dst);
#endif
/*
* copyFile()
*
- * Copies a relation file from src to dst.
+ * Copies a relation file from src to dst.
+ * schemaName/relName are relation's SQL name (used for error messages only).
*/
-const char *
-copyFile(const char *src, const char *dst)
+void
+copyFile(const char *src, const char *dst,
+ const char *schemaName, const char *relName)
{
#ifndef WIN32
- if (copy_file(src, dst) == -1)
-#else
- if (CopyFile(src, dst, true) == 0)
-#endif
- return getErrorText();
- else
- return NULL;
-}
-
-
-/*
- * linkFile()
- *
- * Creates a hard link between the given relation files. We use
- * this function to perform a true in-place update. If the on-disk
- * format of the new cluster is bit-for-bit compatible with the on-disk
- * format of the old cluster, we can simply link each relation
- * instead of copying the data from the old cluster to the new cluster.
- */
-const char *
-linkFile(const char *src, const char *dst)
-{
- if (pg_link_file(src, dst) == -1)
- return getErrorText();
- else
- return NULL;
-}
-
-
-#ifndef WIN32
-static int
-copy_file(const char *srcfile, const char *dstfile)
-{
-#define COPY_BUF_SIZE (50 * BLCKSZ)
-
int src_fd;
int dest_fd;
char *buffer;
- int ret = 0;
- int save_errno = 0;
-
- if ((srcfile == NULL) || (dstfile == NULL))
- {
- errno = EINVAL;
- return -1;
- }
- if ((src_fd = open(srcfile, O_RDONLY | PG_BINARY, 0)) < 0)
- return -1;
+ if ((src_fd = open(src, O_RDONLY | PG_BINARY, 0)) < 0)
+ pg_fatal("error while copying relation \"%s.%s\": could not open file \"%s\": %s\n",
+ schemaName, relName, src, strerror(errno));
- if ((dest_fd = open(dstfile, O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
+ if ((dest_fd = open(dst, O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
S_IRUSR | S_IWUSR)) < 0)
- {
- save_errno = errno;
+ pg_fatal("error while copying relation \"%s.%s\": could not create file \"%s\": %s\n",
+ schemaName, relName, dst, strerror(errno));
- if (src_fd != 0)
- close(src_fd);
-
- errno = save_errno;
- return -1;
- }
+ /* copy in fairly large chunks for best efficiency */
+#define COPY_BUF_SIZE (50 * BLCKSZ)
buffer = (char *) pg_malloc(COPY_BUF_SIZE);
ssize_t nbytes = read(src_fd, buffer, COPY_BUF_SIZE);
if (nbytes < 0)
- {
- save_errno = errno;
- ret = -1;
- break;
- }
+ pg_fatal("error while copying relation \"%s.%s\": could not read file \"%s\": %s\n",
+ schemaName, relName, src, strerror(errno));
if (nbytes == 0)
break;
errno = 0;
-
if (write(dest_fd, buffer, nbytes) != nbytes)
{
/* if write didn't set errno, assume problem is no disk space */
if (errno == 0)
errno = ENOSPC;
- save_errno = errno;
- ret = -1;
- break;
+ pg_fatal("error while copying relation \"%s.%s\": could not write file \"%s\": %s\n",
+ schemaName, relName, dst, strerror(errno));
}
}
pg_free(buffer);
+ close(src_fd);
+ close(dest_fd);
- if (src_fd != 0)
- close(src_fd);
+#else /* WIN32 */
+
+ if (CopyFile(src, dst, true) == 0)
+ {
+ _dosmaperr(GetLastError());
+ pg_fatal("error while copying relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n",
+ schemaName, relName, src, dst, strerror(errno));
+ }
- if (dest_fd != 0)
- close(dest_fd);
+#endif /* WIN32 */
+}
- if (save_errno != 0)
- errno = save_errno;
- return ret;
+/*
+ * linkFile()
+ *
+ * Hard-links a relation file from src to dst.
+ * schemaName/relName are relation's SQL name (used for error messages only).
+ */
+void
+linkFile(const char *src, const char *dst,
+ const char *schemaName, const char *relName)
+{
+ if (pg_link_file(src, dst) < 0)
+ pg_fatal("error while creating link for relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n",
+ schemaName, relName, src, dst, strerror(errno));
}
-#endif
/*
* rewriteVisibilityMap()
*
+ * Transform a visibility map file, copying from src to dst.
+ * schemaName/relName are relation's SQL name (used for error messages only).
+ *
* In versions of PostgreSQL prior to catversion 201603011, PostgreSQL's
* visibility map included one bit per heap page; it now includes two.
* When upgrading a cluster from before that time to a current PostgreSQL
* remain set for the pages for which they were set previously. The
* all-frozen bits are never set by this conversion; we leave that to VACUUM.
*/
-const char *
-rewriteVisibilityMap(const char *fromfile, const char *tofile)
+void
+rewriteVisibilityMap(const char *fromfile, const char *tofile,
+ const char *schemaName, const char *relName)
{
int src_fd;
int dst_fd;
/* Compute number of old-format bytes per new page */
rewriteVmBytesPerPage = (BLCKSZ - SizeOfPageHeaderData) / 2;
- if ((fromfile == NULL) || (tofile == NULL))
- return "Invalid old file or new file";
-
if ((src_fd = open(fromfile, O_RDONLY | PG_BINARY, 0)) < 0)
- return getErrorText();
+ pg_fatal("error while copying relation \"%s.%s\": could not open file \"%s\": %s\n",
+ schemaName, relName, fromfile, strerror(errno));
if (fstat(src_fd, &statbuf) != 0)
- {
- close(src_fd);
- return getErrorText();
- }
+ pg_fatal("error while copying relation \"%s.%s\": could not stat file \"%s\": %s\n",
+ schemaName, relName, fromfile, strerror(errno));
if ((dst_fd = open(tofile, O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
S_IRUSR | S_IWUSR)) < 0)
- {
- close(src_fd);
- return getErrorText();
- }
+ pg_fatal("error while copying relation \"%s.%s\": could not create file \"%s\": %s\n",
+ schemaName, relName, tofile, strerror(errno));
/* Save old file size */
src_filesize = statbuf.st_size;
if ((bytesRead = read(src_fd, buffer, BLCKSZ)) != BLCKSZ)
{
- close(dst_fd);
- close(src_fd);
- return getErrorText();
+ if (bytesRead < 0)
+ pg_fatal("error while copying relation \"%s.%s\": could not read file \"%s\": %s\n",
+ schemaName, relName, fromfile, strerror(errno));
+ else
+ pg_fatal("error while copying relation \"%s.%s\": partial page found in file \"%s\"\n",
+ schemaName, relName, fromfile);
}
totalBytesRead += BLCKSZ;
((PageHeader) new_vmbuf)->pd_checksum =
pg_checksum_page(new_vmbuf, new_blkno);
+ errno = 0;
if (write(dst_fd, new_vmbuf, BLCKSZ) != BLCKSZ)
{
- close(dst_fd);
- close(src_fd);
- return getErrorText();
+ /* if write didn't set errno, assume problem is no disk space */
+ if (errno == 0)
+ errno = ENOSPC;
+ pg_fatal("error while copying relation \"%s.%s\": could not write file \"%s\": %s\n",
+ schemaName, relName, tofile, strerror(errno));
}
/* Advance for next new page */
pg_free(new_vmbuf);
close(dst_fd);
close(src_fd);
-
- return NULL;
}
void
snprintf(new_link_file, sizeof(new_link_file), "%s/PG_VERSION.linktest", new_cluster.pgdata);
unlink(new_link_file); /* might fail */
- if (pg_link_file(existing_file, new_link_file) == -1)
- {
- pg_fatal("Could not create hard link between old and new data directories: %s\n"
+ if (pg_link_file(existing_file, new_link_file) < 0)
+ pg_fatal("could not create hard link between old and new data directories: %s\n"
"In link mode the old and new data directories must be on the same file system volume.\n",
- getErrorText());
- }
+ strerror(errno));
+
unlink(new_link_file);
}
#ifdef WIN32
+/* implementation of pg_link_file() on Windows */
static int
win32_pghardlink(const char *src, const char *dst)
{
* http://msdn.microsoft.com/en-us/library/aa363860(VS.85).aspx
*/
if (CreateHardLinkA(dst, src, NULL) == 0)
+ {
+ _dosmaperr(GetLastError());
return -1;
+ }
else
return 0;
}
FILE *fp;
fp = fopen(path, mode);
- umask(old_umask);
+
+ umask(old_umask); /* we assume this can't change errno */
return fp;
}
found = true;
if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
- pg_fatal("Could not open file \"%s\": %s\n",
- output_path, getErrorText());
- fprintf(script, "Could not load library \"%s\"\n%s\n",
+ pg_fatal("could not open file \"%s\": %s\n",
+ output_path, strerror(errno));
+ fprintf(script, "could not load library \"%s\":\n%s\n",
lib,
PQerrorMessage(conn));
}
if ((output = popen(cmd, "r")) == NULL ||
fgets(cmd_output, sizeof(cmd_output), output) == NULL)
- pg_fatal("Could not get data directory using %s: %s\n",
- cmd, getErrorText());
+ pg_fatal("could not get data directory using %s: %s\n",
+ cmd, strerror(errno));
pclose(output);
/* get path to pg_upgrade executable */
if (find_my_exec(argv0, exec_path) < 0)
- pg_fatal("Could not get path name to pg_upgrade: %s\n", getErrorText());
+ pg_fatal("%s: could not find own program executable\n", argv0);
/* Trim off program name and keep just path */
*last_dir_separator(exec_path) = '\0';
/* file.c */
-const char *copyFile(const char *src, const char *dst);
-const char *linkFile(const char *src, const char *dst);
-const char *rewriteVisibilityMap(const char *fromfile, const char *tofile);
-
+void copyFile(const char *src, const char *dst,
+ const char *schemaName, const char *relName);
+void linkFile(const char *src, const char *dst,
+ const char *schemaName, const char *relName);
+void rewriteVisibilityMap(const char *fromfile, const char *tofile,
+ const char *schemaName, const char *relName);
void check_hard_link(void);
FILE *fopen_priv(const char *path, const char *mode);
void end_progress_output(void);
void prep_status(const char *fmt,...) pg_attribute_printf(1, 2);
void check_ok(void);
-const char *getErrorText(void);
unsigned int str2uint(const char *str);
void pg_putenv(const char *var, const char *val);
static void
transfer_relfile(FileNameMap *map, const char *type_suffix, bool vm_must_add_frozenbit)
{
- const char *msg;
char old_file[MAXPGPATH];
char new_file[MAXPGPATH];
int segno;
else
pg_fatal("error while checking for file existence \"%s.%s\" (\"%s\" to \"%s\"): %s\n",
map->nspname, map->relname, old_file, new_file,
- getErrorText());
+ strerror(errno));
}
/* If file is empty, just return */
/* Copying files might take some time, so give feedback. */
pg_log(PG_STATUS, "%s", old_file);
- if (user_opts.transfer_mode == TRANSFER_MODE_COPY)
+ if (vm_must_add_frozenbit && strcmp(type_suffix, "_vm") == 0)
{
- pg_log(PG_VERBOSE, "copying \"%s\" to \"%s\"\n", old_file, new_file);
-
- /* Rewrite visibility map if needed */
- if (vm_must_add_frozenbit && (strcmp(type_suffix, "_vm") == 0))
- msg = rewriteVisibilityMap(old_file, new_file);
- else
- msg = copyFile(old_file, new_file);
-
- if (msg)
- pg_fatal("error while copying relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n",
- map->nspname, map->relname, old_file, new_file, msg);
+ /* Need to rewrite visibility map format */
+ pg_log(PG_VERBOSE, "rewriting \"%s\" to \"%s\"\n",
+ old_file, new_file);
+ rewriteVisibilityMap(old_file, new_file, map->nspname, map->relname);
+ }
+ else if (user_opts.transfer_mode == TRANSFER_MODE_COPY)
+ {
+ pg_log(PG_VERBOSE, "copying \"%s\" to \"%s\"\n",
+ old_file, new_file);
+ copyFile(old_file, new_file, map->nspname, map->relname);
}
else
{
- pg_log(PG_VERBOSE, "linking \"%s\" to \"%s\"\n", old_file, new_file);
-
- /* Rewrite visibility map if needed */
- if (vm_must_add_frozenbit && (strcmp(type_suffix, "_vm") == 0))
- msg = rewriteVisibilityMap(old_file, new_file);
- else
- msg = linkFile(old_file, new_file);
-
- if (msg)
- pg_fatal("error while creating link for relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n",
- map->nspname, map->relname, old_file, new_file, msg);
+ pg_log(PG_VERBOSE, "linking \"%s\" to \"%s\"\n",
+ old_file, new_file);
+ linkFile(old_file, new_file, map->nspname, map->relname);
}
}
-
- return;
}
os_info.old_tablespaces[tblnum]);
else
report_status(PG_FATAL,
- "cannot stat() tablespace directory \"%s\": %s\n",
- os_info.old_tablespaces[tblnum], getErrorText());
+ "could not stat tablespace directory \"%s\": %s\n",
+ os_info.old_tablespaces[tblnum], strerror(errno));
}
if (!S_ISDIR(statBuf.st_mode))
report_status(PG_FATAL,
}
-/*
- * getErrorText()
- *
- * Returns the text of the most recent error
- */
-const char *
-getErrorText(void)
-{
-#ifdef WIN32
- _dosmaperr(GetLastError());
-#endif
- return pg_strdup(strerror(errno));
-}
-
-
/*
* str2uint()
*
PQExpBufferData connectbuf;
if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
- pg_fatal("could not open file \"%s\": %s\n", output_path, getErrorText());
+ pg_fatal("could not open file \"%s\": %s\n", output_path,
+ strerror(errno));
initPQExpBuffer(&connectbuf);
appendPsqlMetaConnect(&connectbuf, active_db->db_name);
{
found = true;
if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
- pg_fatal("could not open file \"%s\": %s\n", output_path, getErrorText());
+ pg_fatal("could not open file \"%s\": %s\n", output_path,
+ strerror(errno));
if (!db_used)
{
fprintf(script, "Database: %s\n", active_db->db_name);