From 6f56b41ac0cd7092b91834da02e70514d28b8edb Mon Sep 17 00:00:00 2001
From: Robert Haas <rhaas@postgresql.org>
Date: Tue, 8 Mar 2016 08:13:02 -0500
Subject: [PATCH] pg_upgrade: Remove converter plugin facility.

We've not found a use for this so far, and the current need, which
is to convert the visibility map to a new format, does not suit the
existing design anyway.  So just rip it out.

Author: Masahiko Sawada, slightly revised by me.
Discussion: 20160215211313.GB31273@momjian.us
---
 src/bin/pg_upgrade/Makefile      |   2 +-
 src/bin/pg_upgrade/check.c       |   2 -
 src/bin/pg_upgrade/file.c        |  77 +--------------
 src/bin/pg_upgrade/page.c        | 164 -------------------------------
 src/bin/pg_upgrade/pg_upgrade.c  |   2 -
 src/bin/pg_upgrade/pg_upgrade.h  |  37 +------
 src/bin/pg_upgrade/relfilenode.c |  64 ++----------
 7 files changed, 18 insertions(+), 330 deletions(-)
 delete mode 100644 src/bin/pg_upgrade/page.c

diff --git a/src/bin/pg_upgrade/Makefile b/src/bin/pg_upgrade/Makefile
index d9c8145ce00..0c882d9145b 100644
--- a/src/bin/pg_upgrade/Makefile
+++ b/src/bin/pg_upgrade/Makefile
@@ -8,7 +8,7 @@ top_builddir = ../../..
 include $(top_builddir)/src/Makefile.global
 
 OBJS = check.o controldata.o dump.o exec.o file.o function.o info.o \
-       option.o page.o parallel.o pg_upgrade.o relfilenode.o server.o \
+       option.o parallel.o pg_upgrade.o relfilenode.o server.o \
        tablespace.o util.o version.o $(WIN32RES)
 
 override CPPFLAGS := -DDLSUFFIX=\"$(DLSUFFIX)\" -I$(srcdir) -I$(libpq_srcdir) $(CPPFLAGS)
diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c
index e0cb6750c0f..f932094bd0d 100644
--- a/src/bin/pg_upgrade/check.c
+++ b/src/bin/pg_upgrade/check.c
@@ -80,8 +80,6 @@ check_and_dump_old_cluster(bool live_check)
 	if (!live_check)
 		start_postmaster(&old_cluster, true);
 
-	get_pg_database_relfilenode(&old_cluster);
-
 	/* Extract a list of databases and tables from the old cluster */
 	get_db_and_rel_infos(&old_cluster);
 
diff --git a/src/bin/pg_upgrade/file.c b/src/bin/pg_upgrade/file.c
index 9357ad8ce14..2a99a286c6d 100644
--- a/src/bin/pg_upgrade/file.c
+++ b/src/bin/pg_upgrade/file.c
@@ -23,17 +23,13 @@ static int	win32_pghardlink(const char *src, const char *dst);
 
 
 /*
- * copyAndUpdateFile()
+ * copyFile()
  *
- *	Copies a relation file from src to dst.  If pageConverter is non-NULL, this function
- *	uses that pageConverter to do a page-by-page conversion.
+ *	Copies a relation file from src to dst.
  */
 const char *
-copyAndUpdateFile(pageCnvCtx *pageConverter,
-				  const char *src, const char *dst, bool force)
+copyFile(const char *src, const char *dst, bool force)
 {
-	if (pageConverter == NULL)
-	{
 #ifndef WIN32
 		if (copy_file(src, dst, force) == -1)
 #else
@@ -42,70 +38,11 @@ copyAndUpdateFile(pageCnvCtx *pageConverter,
 			return getErrorText();
 		else
 			return NULL;
-	}
-	else
-	{
-		/*
-		 * We have a pageConverter object - that implies that the
-		 * PageLayoutVersion differs between the two clusters so we have to
-		 * perform a page-by-page conversion.
-		 *
-		 * If the pageConverter can convert the entire file at once, invoke
-		 * that plugin function, otherwise, read each page in the relation
-		 * file and call the convertPage plugin function.
-		 */
-
-#ifdef PAGE_CONVERSION
-		if (pageConverter->convertFile)
-			return pageConverter->convertFile(pageConverter->pluginData,
-											  dst, src);
-		else
-#endif
-		{
-			int			src_fd;
-			int			dstfd;
-			char		buf[BLCKSZ];
-			ssize_t		bytesRead;
-			const char *msg = NULL;
-
-			if ((src_fd = open(src, O_RDONLY, 0)) < 0)
-				return "could not open source file";
-
-			if ((dstfd = open(dst, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR)) < 0)
-			{
-				close(src_fd);
-				return "could not create destination file";
-			}
-
-			while ((bytesRead = read(src_fd, buf, BLCKSZ)) == BLCKSZ)
-			{
-#ifdef PAGE_CONVERSION
-				if ((msg = pageConverter->convertPage(pageConverter->pluginData, buf, buf)) != NULL)
-					break;
-#endif
-				if (write(dstfd, buf, BLCKSZ) != BLCKSZ)
-				{
-					msg = "could not write new page to destination";
-					break;
-				}
-			}
-
-			close(src_fd);
-			close(dstfd);
-
-			if (msg)
-				return msg;
-			else if (bytesRead != 0)
-				return "found partial page in source file";
-			else
-				return NULL;
-		}
-	}
 }
 
 
 /*
- * linkAndUpdateFile()
+ * 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
@@ -114,12 +51,8 @@ copyAndUpdateFile(pageCnvCtx *pageConverter,
  * instead of copying the data from the old cluster to the new cluster.
  */
 const char *
-linkAndUpdateFile(pageCnvCtx *pageConverter,
-				  const char *src, const char *dst)
+linkFile(const char *src, const char *dst)
 {
-	if (pageConverter != NULL)
-		return "Cannot in-place update this cluster, page-by-page conversion is required";
-
 	if (pg_link_file(src, dst) == -1)
 		return getErrorText();
 	else
diff --git a/src/bin/pg_upgrade/page.c b/src/bin/pg_upgrade/page.c
deleted file mode 100644
index e5686e583ed..00000000000
--- a/src/bin/pg_upgrade/page.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- *	page.c
- *
- *	per-page conversion operations
- *
- *	Copyright (c) 2010-2016, PostgreSQL Global Development Group
- *	src/bin/pg_upgrade/page.c
- */
-
-#include "postgres_fe.h"
-
-#include "pg_upgrade.h"
-
-#include "storage/bufpage.h"
-
-
-#ifdef PAGE_CONVERSION
-
-
-static void getPageVersion(
-			   uint16 *version, const char *pathName);
-static pageCnvCtx *loadConverterPlugin(
-					uint16 newPageVersion, uint16 oldPageVersion);
-
-
-/*
- * setupPageConverter()
- *
- *	This function determines the PageLayoutVersion of the old cluster and
- *	the PageLayoutVersion of the new cluster.  If the versions differ, this
- *	function loads a converter plugin and returns a pointer to a pageCnvCtx
- *	object (in *result) that knows how to convert pages from the old format
- *	to the new format.  If the versions are identical, this function just
- *	returns a NULL pageCnvCtx pointer to indicate that page-by-page conversion
- *	is not required.
- */
-pageCnvCtx *
-setupPageConverter(void)
-{
-	uint16		oldPageVersion;
-	uint16		newPageVersion;
-	pageCnvCtx *converter;
-	const char *msg;
-	char		dstName[MAXPGPATH];
-	char		srcName[MAXPGPATH];
-
-	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);
-
-	getPageVersion(&oldPageVersion, srcName);
-	getPageVersion(&newPageVersion, dstName);
-
-	/*
-	 * If the old cluster and new cluster use the same page layouts, then we
-	 * don't need a page converter.
-	 */
-	if (newPageVersion != oldPageVersion)
-	{
-		/*
-		 * The clusters use differing page layouts, see if we can find a
-		 * plugin that knows how to convert from the old page layout to the
-		 * new page layout.
-		 */
-
-		if ((converter = loadConverterPlugin(newPageVersion, oldPageVersion)) == NULL)
-			pg_fatal("could not find plugin to convert from old page layout to new page layout\n");
-
-		return converter;
-	}
-	else
-		return NULL;
-}
-
-
-/*
- * getPageVersion()
- *
- *	Retrieves the PageLayoutVersion for the given relation.
- *
- *	Returns NULL on success (and stores the PageLayoutVersion at *version),
- *	if an error occurs, this function returns an error message (in the form
- *	of a null-terminated string).
- */
-static void
-getPageVersion(uint16 *version, const char *pathName)
-{
-	int			relfd;
-	PageHeaderData page;
-	ssize_t		bytesRead;
-
-	if ((relfd = open(pathName, O_RDONLY, 0)) < 0)
-		pg_fatal("could not open relation %s\n", pathName);
-
-	if ((bytesRead = read(relfd, &page, sizeof(page))) != sizeof(page))
-		pg_fatal("could not read page header of %s\n", pathName);
-
-	*version = PageGetPageLayoutVersion(&page);
-
-	close(relfd);
-
-	return;
-}
-
-
-/*
- * loadConverterPlugin()
- *
- *	This function loads a page-converter plugin library and grabs a
- *	pointer to each of the (interesting) functions provided by that
- *	plugin.  The name of the plugin library is derived from the given
- *	newPageVersion and oldPageVersion.  If a plugin is found, this
- *	function returns a pointer to a pageCnvCtx object (which will contain
- *	a collection of plugin function pointers). If the required plugin
- *	is not found, this function returns NULL.
- */
-static pageCnvCtx *
-loadConverterPlugin(uint16 newPageVersion, uint16 oldPageVersion)
-{
-	char		pluginName[MAXPGPATH];
-	void	   *plugin;
-
-	/*
-	 * Try to find a plugin that can convert pages of oldPageVersion into
-	 * pages of newPageVersion.  For example, if we oldPageVersion = 3 and
-	 * newPageVersion is 4, we search for a plugin named:
-	 * plugins/convertLayout_3_to_4.dll
-	 */
-
-	/*
-	 * FIXME: we are searching for plugins relative to the current directory,
-	 * we should really search relative to our own executable instead.
-	 */
-	snprintf(pluginName, sizeof(pluginName), "./plugins/convertLayout_%d_to_%d%s",
-			 oldPageVersion, newPageVersion, DLSUFFIX);
-
-	if ((plugin = pg_dlopen(pluginName)) == NULL)
-		return NULL;
-	else
-	{
-		pageCnvCtx *result = (pageCnvCtx *) pg_malloc(sizeof(*result));
-
-		result->old.PageVersion = oldPageVersion;
-		result->new.PageVersion = newPageVersion;
-
-		result->startup = (pluginStartup) pg_dlsym(plugin, "init");
-		result->convertFile = (pluginConvertFile) pg_dlsym(plugin, "convertFile");
-		result->convertPage = (pluginConvertPage) pg_dlsym(plugin, "convertPage");
-		result->shutdown = (pluginShutdown) pg_dlsym(plugin, "fini");
-		result->pluginData = NULL;
-
-		/*
-		 * If the plugin has exported an initializer, go ahead and invoke it.
-		 */
-		if (result->startup)
-			result->startup(MIGRATOR_API_VERSION, &result->pluginVersion,
-						newPageVersion, oldPageVersion, &result->pluginData);
-
-		return result;
-	}
-}
-
-#endif
diff --git a/src/bin/pg_upgrade/pg_upgrade.c b/src/bin/pg_upgrade/pg_upgrade.c
index 984c39519df..4f5361a4800 100644
--- a/src/bin/pg_upgrade/pg_upgrade.c
+++ b/src/bin/pg_upgrade/pg_upgrade.c
@@ -260,8 +260,6 @@ prepare_new_cluster(void)
 			  new_cluster.bindir, cluster_conn_opts(&new_cluster),
 			  log_opts.verbose ? "--verbose" : "");
 	check_ok();
-
-	get_pg_database_relfilenode(&new_cluster);
 }
 
 
diff --git a/src/bin/pg_upgrade/pg_upgrade.h b/src/bin/pg_upgrade/pg_upgrade.h
index bc733c42047..61228780d43 100644
--- a/src/bin/pg_upgrade/pg_upgrade.h
+++ b/src/bin/pg_upgrade/pg_upgrade.h
@@ -269,7 +269,6 @@ typedef struct
 	uint32		major_version;	/* PG_VERSION of cluster */
 	char		major_version_str[64];	/* string PG_VERSION of cluster */
 	uint32		bin_version;	/* version returned from pg_ctl */
-	Oid			pg_database_oid;	/* OID of pg_database relation */
 	const char *tablespace_suffix;		/* directory specification */
 } ClusterInfo;
 
@@ -364,40 +363,8 @@ bool		pid_lock_file_exists(const char *datadir);
 
 /* file.c */
 
-#ifdef PAGE_CONVERSION
-typedef const char *(*pluginStartup) (uint16 migratorVersion,
-								uint16 *pluginVersion, uint16 newPageVersion,
-								   uint16 oldPageVersion, void **pluginData);
-typedef const char *(*pluginConvertFile) (void *pluginData,
-								   const char *dstName, const char *srcName);
-typedef const char *(*pluginConvertPage) (void *pluginData,
-								   const char *dstPage, const char *srcPage);
-typedef const char *(*pluginShutdown) (void *pluginData);
-
-typedef struct
-{
-	uint16		oldPageVersion; /* Page layout version of the old cluster		*/
-	uint16		newPageVersion; /* Page layout version of the new cluster		*/
-	uint16		pluginVersion;	/* API version of converter plugin */
-	void	   *pluginData;		/* Plugin data (set by plugin) */
-	pluginStartup startup;		/* Pointer to plugin's startup function */
-	pluginConvertFile convertFile;		/* Pointer to plugin's file converter
-										 * function */
-	pluginConvertPage convertPage;		/* Pointer to plugin's page converter
-										 * function */
-	pluginShutdown shutdown;	/* Pointer to plugin's shutdown function */
-} pageCnvCtx;
-
-const pageCnvCtx *setupPageConverter(void);
-#else
-/* dummy */
-typedef void *pageCnvCtx;
-#endif
-
-const char *copyAndUpdateFile(pageCnvCtx *pageConverter, const char *src,
-				  const char *dst, bool force);
-const char *linkAndUpdateFile(pageCnvCtx *pageConverter, const char *src,
-				  const char *dst);
+const char *copyFile(const char *src, const char *dst, bool force);
+const char *linkFile(const char *src, const char *dst);
 
 void		check_hard_link(void);
 FILE	   *fopen_priv(const char *path, const char *mode);
diff --git a/src/bin/pg_upgrade/relfilenode.c b/src/bin/pg_upgrade/relfilenode.c
index c059c5b37d0..b20f073ef71 100644
--- a/src/bin/pg_upgrade/relfilenode.c
+++ b/src/bin/pg_upgrade/relfilenode.c
@@ -15,10 +15,8 @@
 #include "access/transam.h"
 
 
-static void transfer_single_new_db(pageCnvCtx *pageConverter,
-					   FileNameMap *maps, int size, char *old_tablespace);
-static void transfer_relfile(pageCnvCtx *pageConverter, FileNameMap *map,
-				 const char *suffix);
+static void transfer_single_new_db(FileNameMap *maps, int size, char *old_tablespace);
+static void transfer_relfile(FileNameMap *map, const char *suffix);
 
 
 /*
@@ -92,7 +90,6 @@ transfer_all_new_dbs(DbInfoArr *old_db_arr, DbInfoArr *new_db_arr,
 				   *new_db = NULL;
 		FileNameMap *mappings;
 		int			n_maps;
-		pageCnvCtx *pageConverter = NULL;
 
 		/*
 		 * Advance past any databases that exist in the new cluster but not in
@@ -116,11 +113,7 @@ transfer_all_new_dbs(DbInfoArr *old_db_arr, DbInfoArr *new_db_arr,
 		{
 			print_maps(mappings, n_maps, new_db->db_name);
 
-#ifdef PAGE_CONVERSION
-			pageConverter = setupPageConverter();
-#endif
-			transfer_single_new_db(pageConverter, mappings, n_maps,
-								   old_tablespace);
+			transfer_single_new_db(mappings, n_maps, old_tablespace);
 		}
 		/* We allocate something even for n_maps == 0 */
 		pg_free(mappings);
@@ -129,45 +122,13 @@ transfer_all_new_dbs(DbInfoArr *old_db_arr, DbInfoArr *new_db_arr,
 	return;
 }
 
-
-/*
- * get_pg_database_relfilenode()
- *
- *	Retrieves the relfilenode for a few system-catalog tables.  We need these
- *	relfilenodes later in the upgrade process.
- */
-void
-get_pg_database_relfilenode(ClusterInfo *cluster)
-{
-	PGconn	   *conn = connectToServer(cluster, "template1");
-	PGresult   *res;
-	int			i_relfile;
-
-	res = executeQueryOrDie(conn,
-							"SELECT c.relname, c.relfilenode "
-							"FROM	pg_catalog.pg_class c, "
-							"		pg_catalog.pg_namespace n "
-							"WHERE	c.relnamespace = n.oid AND "
-							"		n.nspname = 'pg_catalog' AND "
-							"		c.relname = 'pg_database' "
-							"ORDER BY c.relname");
-
-	i_relfile = PQfnumber(res, "relfilenode");
-	cluster->pg_database_oid = atooid(PQgetvalue(res, 0, i_relfile));
-
-	PQclear(res);
-	PQfinish(conn);
-}
-
-
 /*
  * transfer_single_new_db()
  *
  * create links for mappings stored in "maps" array.
  */
 static void
-transfer_single_new_db(pageCnvCtx *pageConverter,
-					   FileNameMap *maps, int size, char *old_tablespace)
+transfer_single_new_db(FileNameMap *maps, int size, char *old_tablespace)
 {
 	int			mapnum;
 	bool		vm_crashsafe_match = true;
@@ -186,7 +147,7 @@ transfer_single_new_db(pageCnvCtx *pageConverter,
 			strcmp(maps[mapnum].old_tablespace, old_tablespace) == 0)
 		{
 			/* transfer primary file */
-			transfer_relfile(pageConverter, &maps[mapnum], "");
+			transfer_relfile(&maps[mapnum], "");
 
 			/* fsm/vm files added in PG 8.4 */
 			if (GET_MAJOR_VERSION(old_cluster.major_version) >= 804)
@@ -194,9 +155,9 @@ transfer_single_new_db(pageCnvCtx *pageConverter,
 				/*
 				 * Copy/link any fsm and vm files, if they exist
 				 */
-				transfer_relfile(pageConverter, &maps[mapnum], "_fsm");
+				transfer_relfile(&maps[mapnum], "_fsm");
 				if (vm_crashsafe_match)
-					transfer_relfile(pageConverter, &maps[mapnum], "_vm");
+					transfer_relfile(&maps[mapnum], "_vm");
 			}
 		}
 	}
@@ -209,8 +170,7 @@ transfer_single_new_db(pageCnvCtx *pageConverter,
  * Copy or link file from old cluster to new one.
  */
 static void
-transfer_relfile(pageCnvCtx *pageConverter, FileNameMap *map,
-				 const char *type_suffix)
+transfer_relfile(FileNameMap *map, const char *type_suffix)
 {
 	const char *msg;
 	char		old_file[MAXPGPATH];
@@ -268,15 +228,11 @@ transfer_relfile(pageCnvCtx *pageConverter, FileNameMap *map,
 		/* Copying files might take some time, so give feedback. */
 		pg_log(PG_STATUS, "%s", old_file);
 
-		if ((user_opts.transfer_mode == TRANSFER_MODE_LINK) && (pageConverter != NULL))
-			pg_fatal("This upgrade requires page-by-page conversion, "
-					 "you must use copy mode instead of link mode.\n");
-
 		if (user_opts.transfer_mode == TRANSFER_MODE_COPY)
 		{
 			pg_log(PG_VERBOSE, "copying \"%s\" to \"%s\"\n", old_file, new_file);
 
-			if ((msg = copyAndUpdateFile(pageConverter, old_file, new_file, true)) != NULL)
+			if ((msg = copyFile(old_file, new_file, true)) != NULL)
 				pg_fatal("error while copying relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n",
 						 map->nspname, map->relname, old_file, new_file, msg);
 		}
@@ -284,7 +240,7 @@ transfer_relfile(pageCnvCtx *pageConverter, FileNameMap *map,
 		{
 			pg_log(PG_VERBOSE, "linking \"%s\" to \"%s\"\n", old_file, new_file);
 
-			if ((msg = linkAndUpdateFile(pageConverter, old_file, new_file)) != NULL)
+			if ((msg = linkFile(old_file, new_file)) != NULL)
 				pg_fatal("error while creating link for relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n",
 						 map->nspname, map->relname, old_file, new_file, msg);
 		}
-- 
GitLab