Commit e13f7e9a authored by Bruce Momjian's avatar Bruce Momjian

Restructure the pg_upgrade code to use several global structures rather

than packing everything into 'ctx' and passing that to every function.
parent 6e74a91b
This diff is collapsed.
This diff is collapsed.
......@@ -12,20 +12,20 @@
void
generate_old_dump(migratorContext *ctx)
generate_old_dump(void)
{
/* run new pg_dumpall binary */
prep_status(ctx, "Creating catalog dump");
prep_status("Creating catalog dump");
/*
* --binary-upgrade records the width of dropped columns in pg_class, and
* restores the frozenid's for databases and relations.
*/
exec_prog(ctx, true,
exec_prog(true,
SYSTEMQUOTE "\"%s/pg_dumpall\" --port %d --username \"%s\" "
"--schema-only --binary-upgrade > \"%s/" ALL_DUMP_FILE "\""
SYSTEMQUOTE, ctx->new.bindir, ctx->old.port, ctx->user, ctx->cwd);
check_ok(ctx);
SYSTEMQUOTE, new_cluster.bindir, old_cluster.port, os_info.user, os_info.cwd);
check_ok();
}
......@@ -42,7 +42,7 @@ generate_old_dump(migratorContext *ctx)
* an error during restore
*/
void
split_old_dump(migratorContext *ctx)
split_old_dump(void)
{
FILE *all_dump,
*globals_dump,
......@@ -55,22 +55,22 @@ split_old_dump(migratorContext *ctx)
char filename[MAXPGPATH];
bool suppressed_username = false;
snprintf(filename, sizeof(filename), "%s/%s", ctx->cwd, ALL_DUMP_FILE);
snprintf(filename, sizeof(filename), "%s/%s", os_info.cwd, ALL_DUMP_FILE);
if ((all_dump = fopen(filename, "r")) == NULL)
pg_log(ctx, PG_FATAL, "Cannot open dump file %s\n", filename);
snprintf(filename, sizeof(filename), "%s/%s", ctx->cwd, GLOBALS_DUMP_FILE);
pg_log(PG_FATAL, "Cannot open dump file %s\n", filename);
snprintf(filename, sizeof(filename), "%s/%s", os_info.cwd, GLOBALS_DUMP_FILE);
if ((globals_dump = fopen(filename, "w")) == NULL)
pg_log(ctx, PG_FATAL, "Cannot write to dump file %s\n", filename);
snprintf(filename, sizeof(filename), "%s/%s", ctx->cwd, DB_DUMP_FILE);
pg_log(PG_FATAL, "Cannot write to dump file %s\n", filename);
snprintf(filename, sizeof(filename), "%s/%s", os_info.cwd, DB_DUMP_FILE);
if ((db_dump = fopen(filename, "w")) == NULL)
pg_log(ctx, PG_FATAL, "Cannot write to dump file %s\n", filename);
pg_log(PG_FATAL, "Cannot write to dump file %s\n", filename);
current_output = globals_dump;
/* patterns used to prevent our own username from being recreated */
snprintf(create_role_str, sizeof(create_role_str),
"CREATE ROLE %s;", ctx->user);
"CREATE ROLE %s;", os_info.user);
snprintf(create_role_str_quote, sizeof(create_role_str_quote),
"CREATE ROLE %s;", quote_identifier(ctx, ctx->user));
"CREATE ROLE %s;", quote_identifier(os_info.user));
while (fgets(line, sizeof(line), all_dump) != NULL)
{
......
......@@ -13,9 +13,9 @@
#include <grp.h>
static void check_data_dir(migratorContext *ctx, const char *pg_data);
static void check_bin_dir(migratorContext *ctx, ClusterInfo *cluster);
static int check_exec(migratorContext *ctx, const char *dir, const char *cmdName);
static void check_data_dir(const char *pg_data);
static void check_bin_dir(ClusterInfo *cluster);
static int check_exec(const char *dir, const char *cmdName);
static const char *validate_exec(const char *path);
......@@ -30,7 +30,7 @@ static const char *validate_exec(const char *path);
* instead of returning should an error occur.
*/
int
exec_prog(migratorContext *ctx, bool throw_error, const char *fmt,...)
exec_prog(bool throw_error, const char *fmt,...)
{
va_list args;
int result;
......@@ -40,13 +40,13 @@ exec_prog(migratorContext *ctx, bool throw_error, const char *fmt,...)
vsnprintf(cmd, MAXPGPATH, fmt, args);
va_end(args);
pg_log(ctx, PG_INFO, "%s\n", cmd);
pg_log(PG_INFO, "%s\n", cmd);
result = system(cmd);
if (result != 0)
{
pg_log(ctx, throw_error ? PG_FATAL : PG_INFO,
pg_log(throw_error ? PG_FATAL : PG_INFO,
"\nThere were problems executing %s\n", cmd);
return 1;
}
......@@ -62,7 +62,7 @@ exec_prog(migratorContext *ctx, bool throw_error, const char *fmt,...)
* The check is performed by looking for the existence of postmaster.pid file.
*/
bool
is_server_running(migratorContext *ctx, const char *datadir)
is_server_running(const char *datadir)
{
char path[MAXPGPATH];
int fd;
......@@ -72,7 +72,7 @@ is_server_running(migratorContext *ctx, const char *datadir)
if ((fd = open(path, O_RDONLY, 0)) < 0)
{
if (errno != ENOENT)
pg_log(ctx, PG_FATAL, "\ncould not open file \"%s\" for reading\n",
pg_log(PG_FATAL, "\ncould not open file \"%s\" for reading\n",
path);
return false;
......@@ -92,23 +92,23 @@ is_server_running(migratorContext *ctx, const char *datadir)
* NOTE: May update the values of all parameters
*/
void
verify_directories(migratorContext *ctx)
verify_directories(void)
{
prep_status(ctx, "Checking old data directory (%s)", ctx->old.pgdata);
check_data_dir(ctx, ctx->old.pgdata);
check_ok(ctx);
prep_status("Checking old data directory (%s)", old_cluster.pgdata);
check_data_dir(old_cluster.pgdata);
check_ok();
prep_status(ctx, "Checking old bin directory (%s)", ctx->old.bindir);
check_bin_dir(ctx, &ctx->old);
check_ok(ctx);
prep_status("Checking old bin directory (%s)", old_cluster.bindir);
check_bin_dir(&old_cluster);
check_ok();
prep_status(ctx, "Checking new data directory (%s)", ctx->new.pgdata);
check_data_dir(ctx, ctx->new.pgdata);
check_ok(ctx);
prep_status("Checking new data directory (%s)", new_cluster.pgdata);
check_data_dir(new_cluster.pgdata);
check_ok();
prep_status(ctx, "Checking new bin directory (%s)", ctx->new.bindir);
check_bin_dir(ctx, &ctx->new);
check_ok(ctx);
prep_status("Checking new bin directory (%s)", new_cluster.bindir);
check_bin_dir(&new_cluster);
check_ok();
}
......@@ -122,7 +122,7 @@ verify_directories(migratorContext *ctx)
*
*/
static void
check_data_dir(migratorContext *ctx, const char *pg_data)
check_data_dir(const char *pg_data)
{
char subDirName[MAXPGPATH];
int subdirnum;
......@@ -140,10 +140,10 @@ check_data_dir(migratorContext *ctx, const char *pg_data)
requiredSubdirs[subdirnum]);
if (stat(subDirName, &statBuf) != 0)
report_status(ctx, PG_FATAL, "check for %s failed: %s",
report_status(PG_FATAL, "check for %s failed: %s",
requiredSubdirs[subdirnum], getErrorText(errno));
else if (!S_ISDIR(statBuf.st_mode))
report_status(ctx, PG_FATAL, "%s is not a directory",
report_status(PG_FATAL, "%s is not a directory",
requiredSubdirs[subdirnum]);
}
}
......@@ -158,12 +158,12 @@ check_data_dir(migratorContext *ctx, const char *pg_data)
* exit().
*/
static void
check_bin_dir(migratorContext *ctx, ClusterInfo *cluster)
check_bin_dir(ClusterInfo *cluster)
{
check_exec(ctx, cluster->bindir, "postgres");
check_exec(ctx, cluster->bindir, "psql");
check_exec(ctx, cluster->bindir, "pg_ctl");
check_exec(ctx, cluster->bindir, "pg_dumpall");
check_exec(cluster->bindir, "postgres");
check_exec(cluster->bindir, "psql");
check_exec(cluster->bindir, "pg_ctl");
check_exec(cluster->bindir, "pg_dumpall");
}
......@@ -177,7 +177,7 @@ check_bin_dir(migratorContext *ctx, ClusterInfo *cluster)
* a valid executable, this function returns 0 to indicated failure.
*/
static int
check_exec(migratorContext *ctx, const char *dir, const char *cmdName)
check_exec(const char *dir, const char *cmdName)
{
char path[MAXPGPATH];
const char *errMsg;
......@@ -187,7 +187,7 @@ check_exec(migratorContext *ctx, const char *dir, const char *cmdName)
if ((errMsg = validate_exec(path)) == NULL)
return 1; /* 1 -> first alternative OK */
else
pg_log(ctx, PG_FATAL, "check for %s failed - %s\n", cmdName, errMsg);
pg_log(PG_FATAL, "check for %s failed - %s\n", cmdName, errMsg);
return 0; /* 0 -> neither alternative is acceptable */
}
......
......@@ -22,7 +22,7 @@ static int copy_dir(const char *from, const char *to, bool force);
#endif
#ifndef HAVE_SCANDIR
static int pg_scandir_internal(migratorContext *ctx, const char *dirname,
static int pg_scandir_internal(const char *dirname,
struct dirent *** namelist,
int (*selector) (const struct dirent *));
#endif
......@@ -35,7 +35,7 @@ static int pg_scandir_internal(migratorContext *ctx, const char *dirname,
* uses that pageConverter to do a page-by-page conversion.
*/
const char *
copyAndUpdateFile(migratorContext *ctx, pageCnvCtx *pageConverter,
copyAndUpdateFile(pageCnvCtx *pageConverter,
const char *src, const char *dst, bool force)
{
if (pageConverter == NULL)
......@@ -116,7 +116,7 @@ copyAndUpdateFile(migratorContext *ctx, pageCnvCtx *pageConverter,
* instead of copying the data from the old cluster to the new cluster.
*/
const char *
linkAndUpdateFile(migratorContext *ctx, pageCnvCtx *pageConverter,
linkAndUpdateFile(pageCnvCtx *pageConverter,
const char *src, const char *dst)
{
if (pageConverter != NULL)
......@@ -231,12 +231,12 @@ copy_file(const char *srcfile, const char *dstfile, bool force)
* Wrapper for portable scandir functionality
*/
int
pg_scandir(migratorContext *ctx, const char *dirname,
pg_scandir(const char *dirname,
struct dirent *** namelist,
int (*selector) (const struct dirent *))
{
#ifndef HAVE_SCANDIR
return pg_scandir_internal(ctx, dirname, namelist, selector);
return pg_scandir_internal(dirname, namelist, selector);
/*
* scandir() is originally from BSD 4.3, which had the third argument as
......@@ -277,7 +277,7 @@ pg_scandir(migratorContext *ctx, const char *dirname,
* .2, etc.) and should therefore be invoked a small number of times.
*/
static int
pg_scandir_internal(migratorContext *ctx, const char *dirname,
pg_scandir_internal(const char *dirname,
struct dirent *** namelist, int (*selector) (const struct dirent *))
{
DIR *dirdesc;
......@@ -287,7 +287,7 @@ pg_scandir_internal(migratorContext *ctx, const char *dirname,
size_t entrysize;
if ((dirdesc = opendir(dirname)) == NULL)
pg_log(ctx, PG_FATAL, "Could not open directory \"%s\": %m\n", dirname);
pg_log(PG_FATAL, "Could not open directory \"%s\": %m\n", dirname);
*namelist = NULL;
......@@ -342,18 +342,18 @@ dir_matching_filenames(const struct dirent * scan_ent)
void
check_hard_link(migratorContext *ctx)
check_hard_link(void)
{
char existing_file[MAXPGPATH];
char new_link_file[MAXPGPATH];
snprintf(existing_file, sizeof(existing_file), "%s/PG_VERSION", ctx->old.pgdata);
snprintf(new_link_file, sizeof(new_link_file), "%s/PG_VERSION.linktest", ctx->new.pgdata);
snprintf(existing_file, sizeof(existing_file), "%s/PG_VERSION", old_cluster.pgdata);
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_log(ctx, PG_FATAL,
pg_log(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(errno));
......
......@@ -19,65 +19,65 @@
* backend behavior.
*/
void
install_support_functions(migratorContext *ctx)
install_support_functions(void)
{
int dbnum;
prep_status(ctx, "Adding support functions to new cluster");
prep_status("Adding support functions to new cluster");
for (dbnum = 0; dbnum < ctx->new.dbarr.ndbs; dbnum++)
for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
{
DbInfo *newdb = &ctx->new.dbarr.dbs[dbnum];
PGconn *conn = connectToServer(ctx, newdb->db_name, CLUSTER_NEW);
DbInfo *newdb = &new_cluster.dbarr.dbs[dbnum];
PGconn *conn = connectToServer(newdb->db_name, CLUSTER_NEW);
/* suppress NOTICE of dropped objects */
PQclear(executeQueryOrDie(ctx, conn,
PQclear(executeQueryOrDie(conn,
"SET client_min_messages = warning;"));
PQclear(executeQueryOrDie(ctx, conn,
PQclear(executeQueryOrDie(conn,
"DROP SCHEMA IF EXISTS binary_upgrade CASCADE;"));
PQclear(executeQueryOrDie(ctx, conn,
PQclear(executeQueryOrDie(conn,
"RESET client_min_messages;"));
PQclear(executeQueryOrDie(ctx, conn,
PQclear(executeQueryOrDie(conn,
"CREATE SCHEMA binary_upgrade;"));
PQclear(executeQueryOrDie(ctx, conn,
PQclear(executeQueryOrDie(conn,
"CREATE OR REPLACE FUNCTION "
" binary_upgrade.set_next_pg_type_oid(OID) "
"RETURNS VOID "
"AS '$libdir/pg_upgrade_support' "
"LANGUAGE C STRICT;"));
PQclear(executeQueryOrDie(ctx, conn,
PQclear(executeQueryOrDie(conn,
"CREATE OR REPLACE FUNCTION "
" binary_upgrade.set_next_pg_type_array_oid(OID) "
"RETURNS VOID "
"AS '$libdir/pg_upgrade_support' "
"LANGUAGE C STRICT;"));
PQclear(executeQueryOrDie(ctx, conn,
PQclear(executeQueryOrDie(conn,
"CREATE OR REPLACE FUNCTION "
" binary_upgrade.set_next_pg_type_toast_oid(OID) "
"RETURNS VOID "
"AS '$libdir/pg_upgrade_support' "
"LANGUAGE C STRICT;"));
PQclear(executeQueryOrDie(ctx, conn,
PQclear(executeQueryOrDie(conn,
"CREATE OR REPLACE FUNCTION "
" binary_upgrade.set_next_heap_relfilenode(OID) "
"RETURNS VOID "
"AS '$libdir/pg_upgrade_support' "
"LANGUAGE C STRICT;"));
PQclear(executeQueryOrDie(ctx, conn,
PQclear(executeQueryOrDie(conn,
"CREATE OR REPLACE FUNCTION "
" binary_upgrade.set_next_toast_relfilenode(OID) "
"RETURNS VOID "
"AS '$libdir/pg_upgrade_support' "
"LANGUAGE C STRICT;"));
PQclear(executeQueryOrDie(ctx, conn,
PQclear(executeQueryOrDie(conn,
"CREATE OR REPLACE FUNCTION "
" binary_upgrade.set_next_index_relfilenode(OID) "
"RETURNS VOID "
"AS '$libdir/pg_upgrade_support' "
"LANGUAGE C STRICT;"));
PQclear(executeQueryOrDie(ctx, conn,
PQclear(executeQueryOrDie(conn,
"CREATE OR REPLACE FUNCTION "
" binary_upgrade.add_pg_enum_label(OID, OID, NAME) "
"RETURNS VOID "
......@@ -85,32 +85,32 @@ install_support_functions(migratorContext *ctx)
"LANGUAGE C STRICT;"));
PQfinish(conn);
}
check_ok(ctx);
check_ok();
}
void
uninstall_support_functions(migratorContext *ctx)
uninstall_support_functions(void)
{
int dbnum;
prep_status(ctx, "Removing support functions from new cluster");
prep_status("Removing support functions from new cluster");
for (dbnum = 0; dbnum < ctx->new.dbarr.ndbs; dbnum++)
for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
{
DbInfo *newdb = &ctx->new.dbarr.dbs[dbnum];
PGconn *conn = connectToServer(ctx, newdb->db_name, CLUSTER_NEW);
DbInfo *newdb = &new_cluster.dbarr.dbs[dbnum];
PGconn *conn = connectToServer(newdb->db_name, CLUSTER_NEW);
/* suppress NOTICE of dropped objects */
PQclear(executeQueryOrDie(ctx, conn,
PQclear(executeQueryOrDie(conn,
"SET client_min_messages = warning;"));
PQclear(executeQueryOrDie(ctx, conn,
PQclear(executeQueryOrDie(conn,
"DROP SCHEMA binary_upgrade CASCADE;"));
PQclear(executeQueryOrDie(ctx, conn,
PQclear(executeQueryOrDie(conn,
"RESET client_min_messages;"));
PQfinish(conn);
}
check_ok(ctx);
check_ok();
}
......@@ -121,25 +121,25 @@ uninstall_support_functions(migratorContext *ctx)
* We will later check that they all exist in the new installation.
*/
void
get_loadable_libraries(migratorContext *ctx)
get_loadable_libraries(void)
{
ClusterInfo *active_cluster = &ctx->old;
ClusterInfo *active_cluster = &old_cluster;
PGresult **ress;
int totaltups;
int dbnum;
ress = (PGresult **)
pg_malloc(ctx, active_cluster->dbarr.ndbs * sizeof(PGresult *));
pg_malloc(active_cluster->dbarr.ndbs * sizeof(PGresult *));
totaltups = 0;
/* Fetch all library names, removing duplicates within each DB */
for (dbnum = 0; dbnum < active_cluster->dbarr.ndbs; dbnum++)
{
DbInfo *active_db = &active_cluster->dbarr.dbs[dbnum];
PGconn *conn = connectToServer(ctx, active_db->db_name, CLUSTER_OLD);
PGconn *conn = connectToServer(active_db->db_name, CLUSTER_OLD);
/* Fetch all libraries referenced in this DB */
ress[dbnum] = executeQueryOrDie(ctx, conn,
ress[dbnum] = executeQueryOrDie(conn,
"SELECT DISTINCT probin "
"FROM pg_catalog.pg_proc "
"WHERE prolang = 13 /* C */ AND "
......@@ -153,9 +153,9 @@ get_loadable_libraries(migratorContext *ctx)
/* Allocate what's certainly enough space */
if (totaltups > 0)
ctx->libraries = (char **) pg_malloc(ctx, totaltups * sizeof(char *));
os_info.libraries = (char **) pg_malloc(totaltups * sizeof(char *));
else
ctx->libraries = NULL;
os_info.libraries = NULL;
/*
* Now remove duplicates across DBs. This is pretty inefficient code, but
......@@ -178,20 +178,20 @@ get_loadable_libraries(migratorContext *ctx)
for (n = 0; n < totaltups; n++)
{
if (strcmp(lib, ctx->libraries[n]) == 0)
if (strcmp(lib, os_info.libraries[n]) == 0)
{
dup = true;
break;
}
}
if (!dup)
ctx->libraries[totaltups++] = pg_strdup(ctx, lib);
os_info.libraries[totaltups++] = pg_strdup(lib);
}
PQclear(res);
}
ctx->num_libraries = totaltups;
os_info.num_libraries = totaltups;
pg_free(ress);
}
......@@ -205,24 +205,24 @@ get_loadable_libraries(migratorContext *ctx)
* compatibility as well as presence.
*/
void
check_loadable_libraries(migratorContext *ctx)
check_loadable_libraries(void)
{
PGconn *conn = connectToServer(ctx, "template1", CLUSTER_NEW);
PGconn *conn = connectToServer("template1", CLUSTER_NEW);
int libnum;
FILE *script = NULL;
bool found = false;
char output_path[MAXPGPATH];
prep_status(ctx, "Checking for presence of required libraries");
prep_status("Checking for presence of required libraries");
snprintf(output_path, sizeof(output_path), "%s/loadable_libraries.txt",
ctx->cwd);
os_info.cwd);
for (libnum = 0; libnum < ctx->num_libraries; libnum++)
for (libnum = 0; libnum < os_info.num_libraries; libnum++)
{
char *lib = ctx->libraries[libnum];
char *lib = os_info.libraries[libnum];
int llen = strlen(lib);
char *cmd = (char *) pg_malloc(ctx, 8 + 2 * llen + 1);
char *cmd = (char *) pg_malloc(8 + 2 * llen + 1);
PGresult *res;
strcpy(cmd, "LOAD '");
......@@ -235,7 +235,7 @@ check_loadable_libraries(migratorContext *ctx)
{
found = true;
if (script == NULL && (script = fopen(output_path, "w")) == NULL)
pg_log(ctx, PG_FATAL, "Could not create necessary file: %s\n",
pg_log(PG_FATAL, "Could not create necessary file: %s\n",
output_path);
fprintf(script, "Failed to load library: %s\n%s\n",
lib,
......@@ -251,8 +251,8 @@ check_loadable_libraries(migratorContext *ctx)
if (found)
{
fclose(script);
pg_log(ctx, PG_REPORT, "fatal\n");
pg_log(ctx, PG_FATAL,
pg_log(PG_REPORT, "fatal\n");
pg_log(PG_FATAL,
"| Your installation references loadable libraries that are missing\n"
"| from the new installation. You can add these libraries to\n"
"| the new installation, or remove the functions using them\n"
......@@ -261,5 +261,5 @@ check_loadable_libraries(migratorContext *ctx)
"| \"%s\".\n\n", output_path);
}
else
check_ok(ctx);
check_ok();
}
This diff is collapsed.
......@@ -16,11 +16,14 @@
#endif
static void usage(migratorContext *ctx);
static void validateDirectoryOption(migratorContext *ctx, char **dirpath,
static void usage(void);
static void validateDirectoryOption(char **dirpath,
char *envVarName, char *cmdLineOption, char *description);
static void get_pkglibdirs(migratorContext *ctx);
static char *get_pkglibdir(migratorContext *ctx, const char *bindir);
static void get_pkglibdirs(void);
static char *get_pkglibdir(const char *bindir);
UserOpts user_opts;
/*
......@@ -30,7 +33,7 @@ static char *get_pkglibdir(migratorContext *ctx, const char *bindir);
* and initializes the rest of the object.
*/
void
parseCommandLine(migratorContext *ctx, int argc, char *argv[])
parseCommandLine(int argc, char *argv[])
{
static struct option long_options[] = {
{"old-datadir", required_argument, NULL, 'd'},
......@@ -55,39 +58,39 @@ parseCommandLine(migratorContext *ctx, int argc, char *argv[])
if (getenv("PGUSER"))
{
pg_free(ctx->user);
ctx->user = pg_strdup(ctx, getenv("PGUSER"));
pg_free(os_info.user);
os_info.user = pg_strdup(getenv("PGUSER"));
}
ctx->progname = get_progname(argv[0]);
ctx->old.port = getenv("PGPORT") ? atoi(getenv("PGPORT")) : DEF_PGPORT;
ctx->new.port = getenv("PGPORT") ? atoi(getenv("PGPORT")) : DEF_PGPORT;
os_info.progname = get_progname(argv[0]);
old_cluster.port = getenv("PGPORT") ? atoi(getenv("PGPORT")) : DEF_PGPORT;
new_cluster.port = getenv("PGPORT") ? atoi(getenv("PGPORT")) : DEF_PGPORT;
/* must save value, getenv()'s pointer is not stable */
ctx->transfer_mode = TRANSFER_MODE_COPY;
user_opts.transfer_mode = TRANSFER_MODE_COPY;
/* user lookup and 'root' test must be split because of usage() */
user_id = get_user_info(ctx, &ctx->user);
user_id = get_user_info(&os_info.user);
if (argc > 1)
{
if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-h") == 0 ||
strcmp(argv[1], "-?") == 0)
{
usage(ctx);
exit_nicely(ctx, false);
usage();
exit_nicely(false);
}
if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
{
pg_log(ctx, PG_REPORT, "pg_upgrade " PG_VERSION "\n");
exit_nicely(ctx, false);
pg_log(PG_REPORT, "pg_upgrade " PG_VERSION "\n");
exit_nicely(false);
}
}
if (user_id == 0)
pg_log(ctx, PG_FATAL, "%s: cannot be run as root\n", ctx->progname);
pg_log(PG_FATAL, "%s: cannot be run as root\n", os_info.progname);
getcwd(ctx->cwd, MAXPGPATH);
getcwd(os_info.cwd, MAXPGPATH);
while ((option = getopt_long(argc, argv, "d:D:b:B:cgG:kl:p:P:u:v",
long_options, &optindex)) != -1)
......@@ -95,81 +98,81 @@ parseCommandLine(migratorContext *ctx, int argc, char *argv[])
switch (option)
{
case 'd':
ctx->old.pgdata = pg_strdup(ctx, optarg);
old_cluster.pgdata = pg_strdup(optarg);
break;
case 'D':
ctx->new.pgdata = pg_strdup(ctx, optarg);
new_cluster.pgdata = pg_strdup(optarg);
break;
case 'b':
ctx->old.bindir = pg_strdup(ctx, optarg);
old_cluster.bindir = pg_strdup(optarg);
break;
case 'B':
ctx->new.bindir = pg_strdup(ctx, optarg);
new_cluster.bindir = pg_strdup(optarg);
break;
case 'c':
ctx->check = true;
user_opts.check = true;
break;
case 'g':
pg_log(ctx, PG_REPORT, "Running in debug mode\n");
ctx->debug = true;
pg_log(PG_REPORT, "Running in debug mode\n");
log.debug = true;
break;
case 'G':
if ((ctx->debug_fd = fopen(optarg, "w")) == NULL)
if ((log.debug_fd = fopen(optarg, "w")) == NULL)
{
pg_log(ctx, PG_FATAL, "cannot open debug file\n");
exit_nicely(ctx, false);
pg_log(PG_FATAL, "cannot open debug file\n");
exit_nicely(false);
}
break;
case 'k':
ctx->transfer_mode = TRANSFER_MODE_LINK;
user_opts.transfer_mode = TRANSFER_MODE_LINK;
break;
case 'l':
ctx->logfile = pg_strdup(ctx, optarg);
log.filename = pg_strdup(optarg);
break;
case 'p':
if ((ctx->old.port = atoi(optarg)) <= 0)
if ((old_cluster.port = atoi(optarg)) <= 0)
{
pg_log(ctx, PG_FATAL, "invalid old port number\n");
exit_nicely(ctx, false);
pg_log(PG_FATAL, "invalid old port number\n");
exit_nicely(false);
}
break;
case 'P':
if ((ctx->new.port = atoi(optarg)) <= 0)
if ((new_cluster.port = atoi(optarg)) <= 0)
{
pg_log(ctx, PG_FATAL, "invalid new port number\n");
exit_nicely(ctx, false);
pg_log(PG_FATAL, "invalid new port number\n");
exit_nicely(false);
}
break;
case 'u':
pg_free(ctx->user);
ctx->user = pg_strdup(ctx, optarg);
pg_free(os_info.user);
os_info.user = pg_strdup(optarg);
break;
case 'v':
pg_log(ctx, PG_REPORT, "Running in verbose mode\n");
ctx->verbose = true;
pg_log(PG_REPORT, "Running in verbose mode\n");
log.verbose = true;
break;
default:
pg_log(ctx, PG_FATAL,
pg_log(PG_FATAL,
"Try \"%s --help\" for more information.\n",
ctx->progname);
os_info.progname);
break;
}
}
if (ctx->logfile != NULL)
if (log.filename != NULL)
{
/*
* We must use append mode so output generated by child processes via
......@@ -177,39 +180,39 @@ parseCommandLine(migratorContext *ctx, int argc, char *argv[])
* start.
*/
/* truncate */
if ((ctx->log_fd = fopen(ctx->logfile, "w")) == NULL)
pg_log(ctx, PG_FATAL, "Cannot write to log file %s\n", ctx->logfile);
fclose(ctx->log_fd);
if ((ctx->log_fd = fopen(ctx->logfile, "a")) == NULL)
pg_log(ctx, PG_FATAL, "Cannot write to log file %s\n", ctx->logfile);
if ((log.fd = fopen(log.filename, "w")) == NULL)
pg_log(PG_FATAL, "Cannot write to log file %s\n", log.filename);
fclose(log.fd);
if ((log.fd = fopen(log.filename, "a")) == NULL)
pg_log(PG_FATAL, "Cannot write to log file %s\n", log.filename);
}
else
ctx->logfile = strdup(DEVNULL);
log.filename = strdup(DEVNULL);
/* if no debug file name, output to the terminal */
if (ctx->debug && !ctx->debug_fd)
if (log.debug && !log.debug_fd)
{
ctx->debug_fd = fopen(DEVTTY, "w");
if (!ctx->debug_fd)
pg_log(ctx, PG_FATAL, "Cannot write to terminal\n");
log.debug_fd = fopen(DEVTTY, "w");
if (!log.debug_fd)
pg_log(PG_FATAL, "Cannot write to terminal\n");
}
/* Get values from env if not already set */
validateDirectoryOption(ctx, &ctx->old.pgdata, "OLDDATADIR", "-d",
validateDirectoryOption(&old_cluster.pgdata, "OLDDATADIR", "-d",
"old cluster data resides");
validateDirectoryOption(ctx, &ctx->new.pgdata, "NEWDATADIR", "-D",
validateDirectoryOption(&new_cluster.pgdata, "NEWDATADIR", "-D",
"new cluster data resides");
validateDirectoryOption(ctx, &ctx->old.bindir, "OLDBINDIR", "-b",
validateDirectoryOption(&old_cluster.bindir, "OLDBINDIR", "-b",
"old cluster binaries reside");
validateDirectoryOption(ctx, &ctx->new.bindir, "NEWBINDIR", "-B",
validateDirectoryOption(&new_cluster.bindir, "NEWBINDIR", "-B",
"new cluster binaries reside");
get_pkglibdirs(ctx);
get_pkglibdirs();
}
static void
usage(migratorContext *ctx)
usage(void)
{
printf(_("\nUsage: pg_upgrade [OPTIONS]...\n\
\n\
......@@ -243,7 +246,7 @@ When you run pg_upgrade, you must provide the following information:\n\
\n\
For example:\n\
pg_upgrade -d oldCluster/data -D newCluster/data -b oldCluster/bin -B newCluster/bin\n\
or\n"), ctx->old.port, ctx->new.port, ctx->user);
or\n"), old_cluster.port, new_cluster.port, os_info.user);
#ifndef WIN32
printf(_("\
$ export OLDDATADIR=oldCluster/data\n\
......@@ -275,7 +278,7 @@ or\n"), ctx->old.port, ctx->new.port, ctx->user);
* user hasn't provided the required directory name.
*/
static void
validateDirectoryOption(migratorContext *ctx, char **dirpath,
validateDirectoryOption(char **dirpath,
char *envVarName, char *cmdLineOption, char *description)
{
if (*dirpath == NULL || (strlen(*dirpath) == 0))
......@@ -283,10 +286,10 @@ validateDirectoryOption(migratorContext *ctx, char **dirpath,
const char *envVar;
if ((envVar = getenv(envVarName)) && strlen(envVar))
*dirpath = pg_strdup(ctx, envVar);
*dirpath = pg_strdup(envVar);
else
{
pg_log(ctx, PG_FATAL, "You must identify the directory where the %s\n"
pg_log(PG_FATAL, "You must identify the directory where the %s\n"
"Please use the %s command-line option or the %s environment variable\n",
description, cmdLineOption, envVarName);
}
......@@ -306,15 +309,15 @@ validateDirectoryOption(migratorContext *ctx, char **dirpath,
static void
get_pkglibdirs(migratorContext *ctx)
get_pkglibdirs(void)
{
ctx->old.libpath = get_pkglibdir(ctx, ctx->old.bindir);
ctx->new.libpath = get_pkglibdir(ctx, ctx->new.bindir);
old_cluster.libpath = get_pkglibdir(old_cluster.bindir);
new_cluster.libpath = get_pkglibdir(new_cluster.bindir);
}
static char *
get_pkglibdir(migratorContext *ctx, const char *bindir)
get_pkglibdir(const char *bindir)
{
char cmd[MAXPGPATH];
char bufin[MAX_STRING];
......@@ -324,7 +327,7 @@ get_pkglibdir(migratorContext *ctx, const char *bindir)
snprintf(cmd, sizeof(cmd), "\"%s/pg_config\" --pkglibdir", bindir);
if ((output = popen(cmd, "r")) == NULL)
pg_log(ctx, PG_FATAL, "Could not get pkglibdir data: %s\n",
pg_log(PG_FATAL, "Could not get pkglibdir data: %s\n",
getErrorText(errno));
fgets(bufin, sizeof(bufin), output);
......@@ -338,5 +341,5 @@ get_pkglibdir(migratorContext *ctx, const char *bindir)
if (bufin[i] == '\n')
bufin[i] = '\0';
return pg_strdup(ctx, bufin);
return pg_strdup(bufin);
}
......@@ -15,9 +15,9 @@
#ifdef PAGE_CONVERSION
static const char *getPageVersion(migratorContext *ctx,
static const char *getPageVersion(
uint16 *version, const char *pathName);
static pageCnvCtx *loadConverterPlugin(migratorContext *ctx,
static pageCnvCtx *loadConverterPlugin(
uint16 newPageVersion, uint16 oldPageVersion);
......@@ -37,7 +37,7 @@ static pageCnvCtx *loadConverterPlugin(migratorContext *ctx,
* string.
*/
const char *
setupPageConverter(migratorContext *ctx, pageCnvCtx **result)
setupPageConverter(pageCnvCtx **result)
{
uint16 oldPageVersion;
uint16 newPageVersion;
......@@ -46,15 +46,15 @@ setupPageConverter(migratorContext *ctx, pageCnvCtx **result)
char dstName[MAXPGPATH];
char srcName[MAXPGPATH];
snprintf(dstName, sizeof(dstName), "%s/global/%u", ctx->new.pgdata,
ctx->new.pg_database_oid);
snprintf(srcName, sizeof(srcName), "%s/global/%u", ctx->old.pgdata,
ctx->old.pg_database_oid);
snprintf(dstName, sizeof(dstName), "%s/global/%u", new_cluster.pgdata,
new_cluster.pg_database_oid);
snprintf(srcName, sizeof(srcName), "%s/global/%u", old_cluster.pgdata,
old_cluster.pg_database_oid);
if ((msg = getPageVersion(ctx, &oldPageVersion, srcName)) != NULL)
if ((msg = getPageVersion(&oldPageVersion, srcName)) != NULL)
return msg;
if ((msg = getPageVersion(ctx, &newPageVersion, dstName)) != NULL)
if ((msg = getPageVersion(&newPageVersion, dstName)) != NULL)
return msg;
/*
......@@ -73,7 +73,7 @@ setupPageConverter(migratorContext *ctx, pageCnvCtx **result)
* layout.
*/
if ((converter = loadConverterPlugin(ctx, newPageVersion, oldPageVersion)) == NULL)
if ((converter = loadConverterPlugin(newPageVersion, oldPageVersion)) == NULL)
return "can't find plugin to convert from old page layout to new page layout";
else
{
......@@ -93,7 +93,7 @@ setupPageConverter(migratorContext *ctx, pageCnvCtx **result)
* of a null-terminated string).
*/
static const char *
getPageVersion(migratorContext *ctx, uint16 *version, const char *pathName)
getPageVersion(uint16 *version, const char *pathName)
{
int relfd;
PageHeaderData page;
......@@ -128,7 +128,7 @@ getPageVersion(migratorContext *ctx, uint16 *version, const char *pathName)
* is not found, this function returns NULL.
*/
static pageCnvCtx *
loadConverterPlugin(migratorContext *ctx, uint16 newPageVersion, uint16 oldPageVersion)
loadConverterPlugin(uint16 newPageVersion, uint16 oldPageVersion)
{
char pluginName[MAXPGPATH];
void *plugin;
......@@ -151,7 +151,7 @@ loadConverterPlugin(migratorContext *ctx, uint16 newPageVersion, uint16 oldPageV
return NULL;
else
{
pageCnvCtx *result = (pageCnvCtx *) pg_malloc(ctx, sizeof(*result));
pageCnvCtx *result = (pageCnvCtx *) pg_malloc(sizeof(*result));
result->old.PageVersion = oldPageVersion;
result->new.PageVersion = newPageVersion;
......
This diff is collapsed.
This diff is collapsed.
......@@ -13,9 +13,9 @@
#include "access/transam.h"
static void transfer_single_new_db(migratorContext *ctx, pageCnvCtx *pageConverter,
static void transfer_single_new_db(pageCnvCtx *pageConverter,
FileNameMap *maps, int size);
static void transfer_relfile(migratorContext *ctx, pageCnvCtx *pageConverter,
static void transfer_relfile(pageCnvCtx *pageConverter,
const char *fromfile, const char *tofile,
const char *oldnspname, const char *oldrelname,
const char *newnspname, const char *newrelname);
......@@ -30,13 +30,13 @@ char scandir_file_pattern[MAXPGPATH];
* physically link the databases.
*/
const char *
transfer_all_new_dbs(migratorContext *ctx, DbInfoArr *olddb_arr,
transfer_all_new_dbs(DbInfoArr *olddb_arr,
DbInfoArr *newdb_arr, char *old_pgdata, char *new_pgdata)
{
int dbnum;
const char *msg = NULL;
prep_status(ctx, "Restoring user relation files\n");
prep_status("Restoring user relation files\n");
for (dbnum = 0; dbnum < newdb_arr->ndbs; dbnum++)
{
......@@ -47,24 +47,24 @@ transfer_all_new_dbs(migratorContext *ctx, DbInfoArr *olddb_arr,
pageCnvCtx *pageConverter = NULL;
n_maps = 0;
mappings = gen_db_file_maps(ctx, old_db, new_db, &n_maps, old_pgdata,
mappings = gen_db_file_maps(old_db, new_db, &n_maps, old_pgdata,
new_pgdata);
if (n_maps)
{
print_maps(ctx, mappings, n_maps, new_db->db_name);
print_maps(mappings, n_maps, new_db->db_name);
#ifdef PAGE_CONVERSION
msg = setupPageConverter(ctx, &pageConverter);
msg = setupPageConverter(&pageConverter);
#endif
transfer_single_new_db(ctx, pageConverter, mappings, n_maps);
transfer_single_new_db(pageConverter, mappings, n_maps);
pg_free(mappings);
}
}
prep_status(ctx, ""); /* in case nothing printed */
check_ok(ctx);
prep_status(""); /* in case nothing printed */
check_ok();
return msg;
}
......@@ -77,13 +77,14 @@ transfer_all_new_dbs(migratorContext *ctx, DbInfoArr *olddb_arr,
* relfilenodes later in the upgrade process.
*/
void
get_pg_database_relfilenode(migratorContext *ctx, Cluster whichCluster)
get_pg_database_relfilenode(Cluster whichCluster)
{
PGconn *conn = connectToServer(ctx, "template1", whichCluster);
PGconn *conn = connectToServer("template1", whichCluster);
ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster);
PGresult *res;
int i_relfile;
res = executeQueryOrDie(ctx, conn,
res = executeQueryOrDie(conn,
"SELECT c.relname, c.relfilenode "
"FROM pg_catalog.pg_class c, "
" pg_catalog.pg_namespace n "
......@@ -93,10 +94,7 @@ get_pg_database_relfilenode(migratorContext *ctx, Cluster whichCluster)
"ORDER BY c.relname");
i_relfile = PQfnumber(res, "relfilenode");
if (whichCluster == CLUSTER_OLD)
ctx->old.pg_database_oid = atooid(PQgetvalue(res, 0, i_relfile));
else
ctx->new.pg_database_oid = atooid(PQgetvalue(res, 0, i_relfile));
active_cluster->pg_database_oid = atooid(PQgetvalue(res, 0, i_relfile));
PQclear(res);
PQfinish(conn);
......@@ -109,7 +107,7 @@ get_pg_database_relfilenode(migratorContext *ctx, Cluster whichCluster)
* create links for mappings stored in "maps" array.
*/
static void
transfer_single_new_db(migratorContext *ctx, pageCnvCtx *pageConverter,
transfer_single_new_db(pageCnvCtx *pageConverter,
FileNameMap *maps, int size)
{
int mapnum;
......@@ -123,36 +121,39 @@ transfer_single_new_db(migratorContext *ctx, pageCnvCtx *pageConverter,
/* Copying files might take some time, so give feedback. */
snprintf(old_file, sizeof(old_file), "%s/%u", maps[mapnum].old_file, maps[mapnum].old);
snprintf(new_file, sizeof(new_file), "%s/%u", maps[mapnum].new_file, maps[mapnum].new);
pg_log(ctx, PG_REPORT, OVERWRITE_MESSAGE, old_file);
snprintf(old_file, sizeof(old_file), "%s/%u", maps[mapnum].old_file,
maps[mapnum].old_relfilenode);
snprintf(new_file, sizeof(new_file), "%s/%u", maps[mapnum].new_file,
maps[mapnum].new_relfilenode);
pg_log(PG_REPORT, OVERWRITE_MESSAGE, old_file);
/*
* Copy/link the relation file to the new cluster
*/
unlink(new_file);
transfer_relfile(ctx, pageConverter, old_file, new_file,
transfer_relfile(pageConverter, old_file, new_file,
maps[mapnum].old_nspname, maps[mapnum].old_relname,
maps[mapnum].new_nspname, maps[mapnum].new_relname);
/* fsm/vm files added in PG 8.4 */
if (GET_MAJOR_VERSION(ctx->old.major_version) >= 804)
if (GET_MAJOR_VERSION(old_cluster.major_version) >= 804)
{
/*
* Now copy/link any fsm and vm files, if they exist
*/
snprintf(scandir_file_pattern, sizeof(scandir_file_pattern), "%u_", maps[mapnum].old);
numFiles = pg_scandir(ctx, maps[mapnum].old_file, &namelist, dir_matching_filenames);
snprintf(scandir_file_pattern, sizeof(scandir_file_pattern), "%u_",
maps[mapnum].old_relfilenode);
numFiles = pg_scandir(maps[mapnum].old_file, &namelist, dir_matching_filenames);
while (numFiles--)
{
snprintf(old_file, sizeof(old_file), "%s/%s", maps[mapnum].old_file,
namelist[numFiles]->d_name);
snprintf(new_file, sizeof(new_file), "%s/%u%s", maps[mapnum].new_file,
maps[mapnum].new, strchr(namelist[numFiles]->d_name, '_'));
maps[mapnum].new_relfilenode, strchr(namelist[numFiles]->d_name, '_'));
unlink(new_file);
transfer_relfile(ctx, pageConverter, old_file, new_file,
transfer_relfile(pageConverter, old_file, new_file,
maps[mapnum].old_nspname, maps[mapnum].old_relname,
maps[mapnum].new_nspname, maps[mapnum].new_relname);
......@@ -169,18 +170,19 @@ transfer_single_new_db(migratorContext *ctx, pageCnvCtx *pageConverter,
* relfilenode.3, ... 'fsm' and 'vm' files use underscores so are not
* copied.
*/
snprintf(scandir_file_pattern, sizeof(scandir_file_pattern), "%u.", maps[mapnum].old);
numFiles = pg_scandir(ctx, maps[mapnum].old_file, &namelist, dir_matching_filenames);
snprintf(scandir_file_pattern, sizeof(scandir_file_pattern), "%u.",
maps[mapnum].old_relfilenode);
numFiles = pg_scandir(maps[mapnum].old_file, &namelist, dir_matching_filenames);
while (numFiles--)
{
snprintf(old_file, sizeof(old_file), "%s/%s", maps[mapnum].old_file,
namelist[numFiles]->d_name);
snprintf(new_file, sizeof(new_file), "%s/%u%s", maps[mapnum].new_file,
maps[mapnum].new, strchr(namelist[numFiles]->d_name, '.'));
maps[mapnum].new_relfilenode, strchr(namelist[numFiles]->d_name, '.'));
unlink(new_file);
transfer_relfile(ctx, pageConverter, old_file, new_file,
transfer_relfile(pageConverter, old_file, new_file,
maps[mapnum].old_nspname, maps[mapnum].old_relname,
maps[mapnum].new_nspname, maps[mapnum].new_relname);
......@@ -198,30 +200,30 @@ transfer_single_new_db(migratorContext *ctx, pageCnvCtx *pageConverter,
* Copy or link file from old cluster to new one.
*/
static void
transfer_relfile(migratorContext *ctx, pageCnvCtx *pageConverter, const char *oldfile,
transfer_relfile(pageCnvCtx *pageConverter, const char *oldfile,
const char *newfile, const char *oldnspname, const char *oldrelname,
const char *newnspname, const char *newrelname)
{
const char *msg;
if ((ctx->transfer_mode == TRANSFER_MODE_LINK) && (pageConverter != NULL))
pg_log(ctx, PG_FATAL, "this migration requires page-by-page conversion, "
if ((user_opts.transfer_mode == TRANSFER_MODE_LINK) && (pageConverter != NULL))
pg_log(PG_FATAL, "this migration requires page-by-page conversion, "
"you must use copy-mode instead of link-mode\n");
if (ctx->transfer_mode == TRANSFER_MODE_COPY)
if (user_opts.transfer_mode == TRANSFER_MODE_COPY)
{
pg_log(ctx, PG_INFO, "copying %s to %s\n", oldfile, newfile);
pg_log(PG_INFO, "copying %s to %s\n", oldfile, newfile);
if ((msg = copyAndUpdateFile(ctx, pageConverter, oldfile, newfile, true)) != NULL)
pg_log(ctx, PG_FATAL, "error while copying %s.%s(%s) to %s.%s(%s): %s\n",
if ((msg = copyAndUpdateFile(pageConverter, oldfile, newfile, true)) != NULL)
pg_log(PG_FATAL, "error while copying %s.%s(%s) to %s.%s(%s): %s\n",
oldnspname, oldrelname, oldfile, newnspname, newrelname, newfile, msg);
}
else
{
pg_log(ctx, PG_INFO, "linking %s to %s\n", newfile, oldfile);
pg_log(PG_INFO, "linking %s to %s\n", newfile, oldfile);
if ((msg = linkAndUpdateFile(ctx, pageConverter, oldfile, newfile)) != NULL)
pg_log(ctx, PG_FATAL,
if ((msg = linkAndUpdateFile(pageConverter, oldfile, newfile)) != NULL)
pg_log(PG_FATAL,
"error while creating link from %s.%s(%s) to %s.%s(%s): %s\n",
oldnspname, oldrelname, oldfile, newnspname, newrelname,
newfile, msg);
......
......@@ -14,8 +14,8 @@
#define STARTUP_WARNING_TRIES 2
static pgpid_t get_postmaster_pid(migratorContext *ctx, const char *datadir);
static bool test_server_conn(migratorContext *ctx, int timeout,
static pgpid_t get_postmaster_pid(const char *datadir);
static bool test_server_conn(int timeout,
Cluster whichCluster);
......@@ -27,28 +27,28 @@ static bool test_server_conn(migratorContext *ctx, int timeout,
* message and calls exit_nicely() to kill the program.
*/
PGconn *
connectToServer(migratorContext *ctx, const char *db_name,
connectToServer(const char *db_name,
Cluster whichCluster)
{
ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster);
unsigned short port = active_cluster->port;
char connectString[MAXPGPATH];
unsigned short port = (whichCluster == CLUSTER_OLD) ?
ctx->old.port : ctx->new.port;
PGconn *conn;
snprintf(connectString, sizeof(connectString),
"dbname = '%s' user = '%s' port = %d", db_name, ctx->user, port);
"dbname = '%s' user = '%s' port = %d", db_name, os_info.user, port);
conn = PQconnectdb(connectString);
if (conn == NULL || PQstatus(conn) != CONNECTION_OK)
{
pg_log(ctx, PG_REPORT, "Connection to database failed: %s\n",
pg_log(PG_REPORT, "Connection to database failed: %s\n",
PQerrorMessage(conn));
if (conn)
PQfinish(conn);
exit_nicely(ctx, true);
exit_nicely(true);
}
return conn;
......@@ -63,7 +63,7 @@ connectToServer(migratorContext *ctx, const char *db_name,
* message and calls exit_nicely() to kill the program.
*/
PGresult *
executeQueryOrDie(migratorContext *ctx, PGconn *conn, const char *fmt,...)
executeQueryOrDie(PGconn *conn, const char *fmt,...)
{
static char command[8192];
va_list args;
......@@ -74,17 +74,17 @@ executeQueryOrDie(migratorContext *ctx, PGconn *conn, const char *fmt,...)
vsnprintf(command, sizeof(command), fmt, args);
va_end(args);
pg_log(ctx, PG_DEBUG, "executing: %s\n", command);
pg_log(PG_DEBUG, "executing: %s\n", command);
result = PQexec(conn, command);
status = PQresultStatus(result);
if ((status != PGRES_TUPLES_OK) && (status != PGRES_COMMAND_OK))
{
pg_log(ctx, PG_REPORT, "DB command failed\n%s\n%s\n", command,
pg_log(PG_REPORT, "DB command failed\n%s\n%s\n", command,
PQerrorMessage(conn));
PQclear(result);
PQfinish(conn);
exit_nicely(ctx, true);
exit_nicely(true);
return NULL; /* Never get here, but keeps compiler happy */
}
else
......@@ -99,7 +99,7 @@ executeQueryOrDie(migratorContext *ctx, PGconn *conn, const char *fmt,...)
* from the postmaster.pid file
*/
static pgpid_t
get_postmaster_pid(migratorContext *ctx, const char *datadir)
get_postmaster_pid(const char *datadir)
{
FILE *pidf;
long pid;
......@@ -114,8 +114,8 @@ get_postmaster_pid(migratorContext *ctx, const char *datadir)
if (fscanf(pidf, "%ld", &pid) != 1)
{
fclose(pidf);
pg_log(ctx, PG_FATAL, "%s: invalid data in PID file \"%s\"\n",
ctx->progname, pid_file);
pg_log(PG_FATAL, "%s: invalid data in PID file \"%s\"\n",
os_info.progname, pid_file);
}
fclose(pidf);
......@@ -132,16 +132,16 @@ get_postmaster_pid(migratorContext *ctx, const char *datadir)
* is retrieved by reading the PG_VERSION file.
*/
uint32
get_major_server_version(migratorContext *ctx, char **verstr, Cluster whichCluster)
get_major_server_version(char **verstr, Cluster whichCluster)
{
const char *datadir = whichCluster == CLUSTER_OLD ?
ctx->old.pgdata : ctx->new.pgdata;
ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster);
const char *datadir = active_cluster->pgdata;
FILE *version_fd;
char ver_file[MAXPGPATH];
int integer_version = 0;
int fractional_version = 0;
*verstr = pg_malloc(ctx, 64);
*verstr = pg_malloc(64);
snprintf(ver_file, sizeof(ver_file), "%s/PG_VERSION", datadir);
if ((version_fd = fopen(ver_file, "r")) == NULL)
......@@ -150,7 +150,7 @@ get_major_server_version(migratorContext *ctx, char **verstr, Cluster whichClust
if (fscanf(version_fd, "%63s", *verstr) == 0 ||
sscanf(*verstr, "%d.%d", &integer_version, &fractional_version) != 2)
{
pg_log(ctx, PG_FATAL, "could not get version from %s\n", datadir);
pg_log(PG_FATAL, "could not get version from %s\n", datadir);
fclose(version_fd);
return 0;
}
......@@ -160,25 +160,17 @@ get_major_server_version(migratorContext *ctx, char **verstr, Cluster whichClust
void
start_postmaster(migratorContext *ctx, Cluster whichCluster, bool quiet)
start_postmaster(Cluster whichCluster, bool quiet)
{
ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster);
char cmd[MAXPGPATH];
const char *bindir;
const char *datadir;
unsigned short port;
if (whichCluster == CLUSTER_OLD)
{
bindir = ctx->old.bindir;
datadir = ctx->old.pgdata;
port = ctx->old.port;
}
else
{
bindir = ctx->new.bindir;
datadir = ctx->new.pgdata;
port = ctx->new.port;
}
bindir = active_cluster->bindir;
datadir = active_cluster->pgdata;
port = active_cluster->port;
/*
* On Win32, we can't send both pg_upgrade output and pg_ctl output to the
......@@ -193,40 +185,40 @@ start_postmaster(migratorContext *ctx, Cluster whichCluster, bool quiet)
"start >> \"%s\" 2>&1" SYSTEMQUOTE,
bindir,
#ifndef WIN32
ctx->logfile, datadir, port, ctx->logfile);
log.filename, datadir, port, log.filename);
#else
DEVNULL, datadir, port, DEVNULL);
#endif
exec_prog(ctx, true, "%s", cmd);
exec_prog(true, "%s", cmd);
/* wait for the server to start properly */
if (test_server_conn(ctx, POSTMASTER_UPTIME, whichCluster) == false)
pg_log(ctx, PG_FATAL, " Unable to start %s postmaster with the command: %s\nPerhaps pg_hba.conf was not set to \"trust\".",
if (test_server_conn(POSTMASTER_UPTIME, whichCluster) == false)
pg_log(PG_FATAL, " Unable to start %s postmaster with the command: %s\nPerhaps pg_hba.conf was not set to \"trust\".",
CLUSTERNAME(whichCluster), cmd);
if ((ctx->postmasterPID = get_postmaster_pid(ctx, datadir)) == 0)
pg_log(ctx, PG_FATAL, " Unable to get postmaster pid\n");
ctx->running_cluster = whichCluster;
if ((os_info.postmasterPID = get_postmaster_pid(datadir)) == 0)
pg_log(PG_FATAL, " Unable to get postmaster pid\n");
os_info.running_cluster = whichCluster;
}
void
stop_postmaster(migratorContext *ctx, bool fast, bool quiet)
stop_postmaster(bool fast, bool quiet)
{
char cmd[MAXPGPATH];
const char *bindir;
const char *datadir;
if (ctx->running_cluster == CLUSTER_OLD)
if (os_info.running_cluster == CLUSTER_OLD)
{
bindir = ctx->old.bindir;
datadir = ctx->old.pgdata;
bindir = old_cluster.bindir;
datadir = old_cluster.pgdata;
}
else if (ctx->running_cluster == CLUSTER_NEW)
else if (os_info.running_cluster == CLUSTER_NEW)
{
bindir = ctx->new.bindir;
datadir = ctx->new.pgdata;
bindir = new_cluster.bindir;
datadir = new_cluster.pgdata;
}
else
return; /* no cluster running */
......@@ -237,14 +229,14 @@ stop_postmaster(migratorContext *ctx, bool fast, bool quiet)
"\"%s\" 2>&1" SYSTEMQUOTE,
bindir,
#ifndef WIN32
ctx->logfile, datadir, fast ? "-m fast" : "", ctx->logfile);
log.filename, datadir, fast ? "-m fast" : "", log.filename);
#else
DEVNULL, datadir, fast ? "-m fast" : "", DEVNULL);
#endif
exec_prog(ctx, fast ? false : true, "%s", cmd);
exec_prog(fast ? false : true, "%s", cmd);
ctx->postmasterPID = 0;
ctx->running_cluster = NONE;
os_info.postmasterPID = 0;
os_info.running_cluster = NONE;
}
......@@ -258,17 +250,17 @@ stop_postmaster(migratorContext *ctx, bool fast, bool quiet)
* Returns true if the connection attempt was successfull, false otherwise.
*/
static bool
test_server_conn(migratorContext *ctx, int timeout, Cluster whichCluster)
test_server_conn(int timeout, Cluster whichCluster)
{
ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster);
unsigned short port = active_cluster->port;
PGconn *conn = NULL;
char con_opts[MAX_STRING];
int tries;
unsigned short port = (whichCluster == CLUSTER_OLD) ?
ctx->old.port : ctx->new.port;
bool ret = false;
snprintf(con_opts, sizeof(con_opts),
"dbname = 'template1' user = '%s' port = %d ", ctx->user, port);
"dbname = 'template1' user = '%s' port = %d ", os_info.user, port);
for (tries = 0; tries < timeout; tries++)
{
......@@ -282,14 +274,14 @@ test_server_conn(migratorContext *ctx, int timeout, Cluster whichCluster)
}
if (tries == STARTUP_WARNING_TRIES)
prep_status(ctx, "Trying to start %s server ",
prep_status("Trying to start %s server ",
CLUSTERNAME(whichCluster));
else if (tries > STARTUP_WARNING_TRIES)
pg_log(ctx, PG_REPORT, ".");
pg_log(PG_REPORT, ".");
}
if (tries > STARTUP_WARNING_TRIES)
check_ok(ctx);
check_ok();
return ret;
}
......@@ -305,7 +297,7 @@ test_server_conn(migratorContext *ctx, int timeout, Cluster whichCluster)
* If any are found, will log them and cancel.
*/
void
check_for_libpq_envvars(migratorContext *ctx)
check_for_libpq_envvars(void)
{
PQconninfoOption *option;
PQconninfoOption *start;
......@@ -323,7 +315,7 @@ check_for_libpq_envvars(migratorContext *ctx)
{
found = true;
pg_log(ctx, PG_WARNING,
pg_log(PG_WARNING,
"libpq env var %-20s is currently set to: %s\n", option->envvar, value);
}
......@@ -334,6 +326,6 @@ check_for_libpq_envvars(migratorContext *ctx)
PQconninfoFree(start);
if (found)
pg_log(ctx, PG_FATAL,
pg_log(PG_FATAL,
"libpq env vars have been found and listed above, please unset them for pg_upgrade\n");
}
......@@ -9,22 +9,22 @@
#include "pg_upgrade.h"
static void get_tablespace_paths(migratorContext *ctx);
static void set_tablespace_directory_suffix(migratorContext *ctx,
static void get_tablespace_paths(void);
static void set_tablespace_directory_suffix(
Cluster whichCluster);
void
init_tablespaces(migratorContext *ctx)
init_tablespaces(void)
{
get_tablespace_paths(ctx);
get_tablespace_paths();
set_tablespace_directory_suffix(ctx, CLUSTER_OLD);
set_tablespace_directory_suffix(ctx, CLUSTER_NEW);
set_tablespace_directory_suffix(CLUSTER_OLD);
set_tablespace_directory_suffix(CLUSTER_NEW);
if (ctx->num_tablespaces > 0 &&
strcmp(ctx->old.tablespace_suffix, ctx->new.tablespace_suffix) == 0)
pg_log(ctx, PG_FATAL,
if (os_info.num_tablespaces > 0 &&
strcmp(old_cluster.tablespace_suffix, new_cluster.tablespace_suffix) == 0)
pg_log(PG_FATAL,
"Cannot migrate to/from the same system catalog version when\n"
"using tablespaces.\n");
}
......@@ -37,29 +37,29 @@ init_tablespaces(migratorContext *ctx)
* paths. Its the caller's responsibility to free the array.
*/
static void
get_tablespace_paths(migratorContext *ctx)
get_tablespace_paths(void)
{
PGconn *conn = connectToServer(ctx, "template1", CLUSTER_OLD);
PGconn *conn = connectToServer("template1", CLUSTER_OLD);
PGresult *res;
int tblnum;
int i_spclocation;
res = executeQueryOrDie(ctx, conn,
res = executeQueryOrDie(conn,
"SELECT spclocation "
"FROM pg_catalog.pg_tablespace "
"WHERE spcname != 'pg_default' AND "
" spcname != 'pg_global'");
if ((ctx->num_tablespaces = PQntuples(res)) != 0)
ctx->tablespaces = (char **) pg_malloc(ctx,
ctx->num_tablespaces * sizeof(char *));
if ((os_info.num_tablespaces = PQntuples(res)) != 0)
os_info.tablespaces = (char **) pg_malloc(
os_info.num_tablespaces * sizeof(char *));
else
ctx->tablespaces = NULL;
os_info.tablespaces = NULL;
i_spclocation = PQfnumber(res, "spclocation");
for (tblnum = 0; tblnum < ctx->num_tablespaces; tblnum++)
ctx->tablespaces[tblnum] = pg_strdup(ctx,
for (tblnum = 0; tblnum < os_info.num_tablespaces; tblnum++)
os_info.tablespaces[tblnum] = pg_strdup(
PQgetvalue(res, tblnum, i_spclocation));
PQclear(res);
......@@ -71,20 +71,21 @@ get_tablespace_paths(migratorContext *ctx)
static void
set_tablespace_directory_suffix(migratorContext *ctx, Cluster whichCluster)
set_tablespace_directory_suffix(Cluster whichCluster)
{
ClusterInfo *cluster = (whichCluster == CLUSTER_OLD) ? &ctx->old : &ctx->new;
ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster);
if (GET_MAJOR_VERSION(cluster->major_version) <= 804)
cluster->tablespace_suffix = pg_strdup(ctx, "");
if (GET_MAJOR_VERSION(active_cluster->major_version) <= 804)
active_cluster->tablespace_suffix = pg_strdup("");
else
{
/* This cluster has a version-specific subdirectory */
cluster->tablespace_suffix = pg_malloc(ctx, 4 + strlen(cluster->major_version_str) +
10 /* OIDCHARS */ + 1);
active_cluster->tablespace_suffix = pg_malloc(4 +
strlen(active_cluster->major_version_str) +
10 /* OIDCHARS */ + 1);
/* The leading slash is needed to start a new directory. */
sprintf(cluster->tablespace_suffix, "/PG_%s_%d", cluster->major_version_str,
cluster->controldata.cat_ver);
sprintf(active_cluster->tablespace_suffix, "/PG_%s_%d", active_cluster->major_version_str,
active_cluster->controldata.cat_ver);
}
}
......@@ -12,13 +12,15 @@
#include <signal.h>
Log log;
/*
* report_status()
*
* Displays the result of an operation (ok, failed, error message,...)
*/
void
report_status(migratorContext *ctx, eLogType type, const char *fmt,...)
report_status(eLogType type, const char *fmt,...)
{
va_list args;
char message[MAX_STRING];
......@@ -27,27 +29,27 @@ report_status(migratorContext *ctx, eLogType type, const char *fmt,...)
vsnprintf(message, sizeof(message), fmt, args);
va_end(args);
pg_log(ctx, type, "%s\n", message);
pg_log(type, "%s\n", message);
}
/*
* prep_status(&ctx, )
* prep_status
*
* Displays a message that describes an operation we are about to begin.
* We pad the message out to MESSAGE_WIDTH characters so that all of the "ok" and
* "failed" indicators line up nicely.
*
* A typical sequence would look like this:
* prep_status(&ctx, "about to flarb the next %d files", fileCount );
* prep_status("about to flarb the next %d files", fileCount );
*
* if(( message = flarbFiles(fileCount)) == NULL)
* report_status(ctx, PG_REPORT, "ok" );
* report_status(PG_REPORT, "ok" );
* else
* pg_log(ctx, PG_FATAL, "failed - %s", message );
* pg_log(PG_FATAL, "failed - %s", message );
*/
void
prep_status(migratorContext *ctx, const char *fmt,...)
prep_status(const char *fmt,...)
{
va_list args;
char message[MAX_STRING];
......@@ -57,14 +59,14 @@ prep_status(migratorContext *ctx, const char *fmt,...)
va_end(args);
if (strlen(message) > 0 && message[strlen(message) - 1] == '\n')
pg_log(ctx, PG_REPORT, "%s", message);
pg_log(PG_REPORT, "%s", message);
else
pg_log(ctx, PG_REPORT, "%-" MESSAGE_WIDTH "s", message);
pg_log(PG_REPORT, "%-" MESSAGE_WIDTH "s", message);
}
void
pg_log(migratorContext *ctx, eLogType type, char *fmt,...)
pg_log(eLogType type, char *fmt,...)
{
va_list args;
char message[MAX_STRING];
......@@ -73,19 +75,19 @@ pg_log(migratorContext *ctx, eLogType type, char *fmt,...)
vsnprintf(message, sizeof(message), fmt, args);
va_end(args);
if (ctx->log_fd != NULL)
if (log.fd != NULL)
{
fwrite(message, strlen(message), 1, ctx->log_fd);
fwrite(message, strlen(message), 1, log.fd);
/* if we are using OVERWRITE_MESSAGE, add newline */
if (strchr(message, '\r') != NULL)
fwrite("\n", 1, 1, ctx->log_fd);
fflush(ctx->log_fd);
fwrite("\n", 1, 1, log.fd);
fflush(log.fd);
}
switch (type)
{
case PG_INFO:
if (ctx->verbose)
if (log.verbose)
printf("%s", _(message));
break;
......@@ -97,12 +99,12 @@ pg_log(migratorContext *ctx, eLogType type, char *fmt,...)
case PG_FATAL:
printf("%s", "\n");
printf("%s", _(message));
exit_nicely(ctx, true);
exit_nicely(true);
break;
case PG_DEBUG:
if (ctx->debug)
fprintf(ctx->debug_fd, "%s\n", _(message));
if (log.debug)
fprintf(log.debug_fd, "%s\n", _(message));
break;
default:
......@@ -113,10 +115,10 @@ pg_log(migratorContext *ctx, eLogType type, char *fmt,...)
void
check_ok(migratorContext *ctx)
check_ok(void)
{
/* all seems well */
report_status(ctx, PG_REPORT, "ok");
report_status(PG_REPORT, "ok");
fflush(stdout);
}
......@@ -129,9 +131,9 @@ check_ok(migratorContext *ctx)
* memory leakage is not a big deal in this program.
*/
char *
quote_identifier(migratorContext *ctx, const char *s)
quote_identifier(const char *s)
{
char *result = pg_malloc(ctx, strlen(s) * 2 + 3);
char *result = pg_malloc(strlen(s) * 2 + 3);
char *r = result;
*r++ = '"';
......@@ -154,7 +156,7 @@ quote_identifier(migratorContext *ctx, const char *s)
* (copied from initdb.c) find the current user
*/
int
get_user_info(migratorContext *ctx, char **user_name)
get_user_info(char **user_name)
{
int user_id;
......@@ -176,28 +178,28 @@ get_user_info(migratorContext *ctx, char **user_name)
user_id = 1;
#endif
*user_name = pg_strdup(ctx, pw->pw_name);
*user_name = pg_strdup(pw->pw_name);
return user_id;
}
void
exit_nicely(migratorContext *ctx, bool need_cleanup)
exit_nicely(bool need_cleanup)
{
stop_postmaster(ctx, true, true);
stop_postmaster(true, true);
pg_free(ctx->logfile);
pg_free(log.filename);
if (ctx->log_fd)
fclose(ctx->log_fd);
if (log.fd)
fclose(log.fd);
if (ctx->debug_fd)
fclose(ctx->debug_fd);
if (log.debug_fd)
fclose(log.debug_fd);
/* terminate any running instance of postmaster */
if (ctx->postmasterPID != 0)
kill(ctx->postmasterPID, SIGTERM);
if (os_info.postmasterPID != 0)
kill(os_info.postmasterPID, SIGTERM);
if (need_cleanup)
{
......@@ -212,12 +214,12 @@ exit_nicely(migratorContext *ctx, bool need_cleanup)
void *
pg_malloc(migratorContext *ctx, int n)
pg_malloc(int n)
{
void *p = malloc(n);
if (p == NULL)
pg_log(ctx, PG_FATAL, "%s: out of memory\n", ctx->progname);
pg_log(PG_FATAL, "%s: out of memory\n", os_info.progname);
return p;
}
......@@ -232,12 +234,12 @@ pg_free(void *p)
char *
pg_strdup(migratorContext *ctx, const char *s)
pg_strdup(const char *s)
{
char *result = strdup(s);
if (result == NULL)
pg_log(ctx, PG_FATAL, "%s: out of memory\n", ctx->progname);
pg_log(PG_FATAL, "%s: out of memory\n", os_info.progname);
return result;
}
......
......@@ -18,30 +18,29 @@
* 9.0 has a new pg_largeobject permission table
*/
void
new_9_0_populate_pg_largeobject_metadata(migratorContext *ctx, bool check_mode,
new_9_0_populate_pg_largeobject_metadata(bool check_mode,
Cluster whichCluster)
{
ClusterInfo *active_cluster = (whichCluster == CLUSTER_OLD) ?
&ctx->old : &ctx->new;
ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster);
int dbnum;
FILE *script = NULL;
bool found = false;
char output_path[MAXPGPATH];
prep_status(ctx, "Checking for large objects");
prep_status("Checking for large objects");
snprintf(output_path, sizeof(output_path), "%s/pg_largeobject.sql",
ctx->cwd);
os_info.cwd);
for (dbnum = 0; dbnum < active_cluster->dbarr.ndbs; dbnum++)
{
PGresult *res;
int i_count;
DbInfo *active_db = &active_cluster->dbarr.dbs[dbnum];
PGconn *conn = connectToServer(ctx, active_db->db_name, whichCluster);
PGconn *conn = connectToServer(active_db->db_name, whichCluster);
/* find if there are any large objects */
res = executeQueryOrDie(ctx, conn,
res = executeQueryOrDie(conn,
"SELECT count(*) "
"FROM pg_catalog.pg_largeobject ");
......@@ -52,9 +51,9 @@ new_9_0_populate_pg_largeobject_metadata(migratorContext *ctx, bool check_mode,
if (!check_mode)
{
if (script == NULL && (script = fopen(output_path, "w")) == NULL)
pg_log(ctx, PG_FATAL, "Could not create necessary file: %s\n", output_path);
pg_log(PG_FATAL, "Could not create necessary file: %s\n", output_path);
fprintf(script, "\\connect %s\n",
quote_identifier(ctx, active_db->db_name));
quote_identifier(active_db->db_name));
fprintf(script,
"SELECT pg_catalog.lo_create(t.loid)\n"
"FROM (SELECT DISTINCT loid FROM pg_catalog.pg_largeobject) AS t;\n");
......@@ -69,16 +68,16 @@ new_9_0_populate_pg_largeobject_metadata(migratorContext *ctx, bool check_mode,
{
if (!check_mode)
fclose(script);
report_status(ctx, PG_WARNING, "warning");
report_status(PG_WARNING, "warning");
if (check_mode)
pg_log(ctx, PG_WARNING, "\n"
pg_log(PG_WARNING, "\n"
"| Your installation contains large objects.\n"
"| The new database has an additional large object\n"
"| permission table. After migration, you will be\n"
"| given a command to populate the pg_largeobject\n"
"| permission table with default permissions.\n\n");
else
pg_log(ctx, PG_WARNING, "\n"
pg_log(PG_WARNING, "\n"
"| Your installation contains large objects.\n"
"| The new database has an additional large object\n"
"| permission table so default permissions must be\n"
......@@ -89,5 +88,5 @@ new_9_0_populate_pg_largeobject_metadata(migratorContext *ctx, bool check_mode,
output_path);
}
else
check_ok(ctx);
check_ok();
}
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment