Commit e09ad07b authored by Michael Paquier's avatar Michael Paquier

Move routine building restore_command to src/common/

restore_command has only been used until now by the backend, but there
is a pending patch for pg_rewind to make use of that in the frontend.

Author: Alexey Kondratov
Reviewed-by: Andrey Borodin, Andres Freund, Alvaro Herrera, Alexander
Korotkov, Michael Paquier
Discussion: https://postgr.es/m/a3acff50-5a0d-9a2c-b3b2-ee36168955c1@postgrespro.ru
parent b8e20d6d
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "access/xlog.h" #include "access/xlog.h"
#include "access/xlog_internal.h" #include "access/xlog_internal.h"
#include "common/archive.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "postmaster/startup.h" #include "postmaster/startup.h"
#include "replication/walsender.h" #include "replication/walsender.h"
...@@ -53,11 +54,8 @@ RestoreArchivedFile(char *path, const char *xlogfname, ...@@ -53,11 +54,8 @@ RestoreArchivedFile(char *path, const char *xlogfname,
bool cleanupEnabled) bool cleanupEnabled)
{ {
char xlogpath[MAXPGPATH]; char xlogpath[MAXPGPATH];
char xlogRestoreCmd[MAXPGPATH]; char *xlogRestoreCmd;
char lastRestartPointFname[MAXPGPATH]; char lastRestartPointFname[MAXPGPATH];
char *dp;
char *endp;
const char *sp;
int rc; int rc;
struct stat stat_buf; struct stat stat_buf;
XLogSegNo restartSegNo; XLogSegNo restartSegNo;
...@@ -149,58 +147,13 @@ RestoreArchivedFile(char *path, const char *xlogfname, ...@@ -149,58 +147,13 @@ RestoreArchivedFile(char *path, const char *xlogfname,
else else
XLogFileName(lastRestartPointFname, 0, 0L, wal_segment_size); XLogFileName(lastRestartPointFname, 0, 0L, wal_segment_size);
/* /* Build the restore command to execute */
* construct the command to be executed xlogRestoreCmd = BuildRestoreCommand(recoveryRestoreCommand,
*/ xlogpath, xlogfname,
dp = xlogRestoreCmd; lastRestartPointFname);
endp = xlogRestoreCmd + MAXPGPATH - 1; if (xlogRestoreCmd == NULL)
*endp = '\0'; elog(ERROR, "could not build restore command \"%s\"",
recoveryRestoreCommand);
for (sp = recoveryRestoreCommand; *sp; sp++)
{
if (*sp == '%')
{
switch (sp[1])
{
case 'p':
/* %p: relative path of target file */
sp++;
StrNCpy(dp, xlogpath, endp - dp);
make_native_path(dp);
dp += strlen(dp);
break;
case 'f':
/* %f: filename of desired file */
sp++;
StrNCpy(dp, xlogfname, endp - dp);
dp += strlen(dp);
break;
case 'r':
/* %r: filename of last restartpoint */
sp++;
StrNCpy(dp, lastRestartPointFname, endp - dp);
dp += strlen(dp);
break;
case '%':
/* convert %% to a single % */
sp++;
if (dp < endp)
*dp++ = *sp;
break;
default:
/* otherwise treat the % as not special */
if (dp < endp)
*dp++ = *sp;
break;
}
}
else
{
if (dp < endp)
*dp++ = *sp;
}
}
*dp = '\0';
ereport(DEBUG3, ereport(DEBUG3,
(errmsg_internal("executing restore command \"%s\"", (errmsg_internal("executing restore command \"%s\"",
...@@ -217,6 +170,7 @@ RestoreArchivedFile(char *path, const char *xlogfname, ...@@ -217,6 +170,7 @@ RestoreArchivedFile(char *path, const char *xlogfname,
rc = system(xlogRestoreCmd); rc = system(xlogRestoreCmd);
PostRestoreCommand(); PostRestoreCommand();
pfree(xlogRestoreCmd);
if (rc == 0) if (rc == 0)
{ {
......
...@@ -46,6 +46,7 @@ LIBS += $(PTHREAD_LIBS) ...@@ -46,6 +46,7 @@ LIBS += $(PTHREAD_LIBS)
# If you add objects here, see also src/tools/msvc/Mkvcbuild.pm # If you add objects here, see also src/tools/msvc/Mkvcbuild.pm
OBJS_COMMON = \ OBJS_COMMON = \
archive.o \
base64.o \ base64.o \
config_info.o \ config_info.o \
controldata_utils.o \ controldata_utils.o \
......
/*-------------------------------------------------------------------------
*
* archive.c
* Common WAL archive routines
*
* Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* src/common/archive.c
*
*-------------------------------------------------------------------------
*/
#ifndef FRONTEND
#include "postgres.h"
#else
#include "postgres_fe.h"
#endif
#include "common/archive.h"
#include "lib/stringinfo.h"
/*
* BuildRestoreCommand
*
* Builds a restore command to retrieve a file from WAL archives, replacing
* the supported aliases with values supplied by the caller as defined by
* the GUC parameter restore_command: xlogpath for %p, xlogfname for %f and
* lastRestartPointFname for %r.
*
* The result is a palloc'd string for the restore command built. The
* caller is responsible for freeing it. If any of the required arguments
* is NULL and that the corresponding alias is found in the command given
* by the caller, then NULL is returned.
*/
char *
BuildRestoreCommand(const char *restoreCommand,
const char *xlogpath,
const char *xlogfname,
const char *lastRestartPointFname)
{
StringInfoData result;
const char *sp;
/*
* Build the command to be executed.
*/
initStringInfo(&result);
for (sp = restoreCommand; *sp; sp++)
{
if (*sp == '%')
{
switch (sp[1])
{
case 'p':
{
char *nativePath;
/* %p: relative path of target file */
if (xlogpath == NULL)
{
pfree(result.data);
return NULL;
}
sp++;
/*
* This needs to use a placeholder to not modify the
* input with the conversion done via
* make_native_path().
*/
nativePath = pstrdup(xlogpath);
make_native_path(nativePath);
appendStringInfoString(&result,
nativePath);
pfree(nativePath);
break;
}
case 'f':
/* %f: filename of desired file */
if (xlogfname == NULL)
{
pfree(result.data);
return NULL;
}
sp++;
appendStringInfoString(&result, xlogfname);
break;
case 'r':
/* %r: filename of last restartpoint */
if (lastRestartPointFname == NULL)
{
pfree(result.data);
return NULL;
}
sp++;
appendStringInfoString(&result,
lastRestartPointFname);
break;
case '%':
/* convert %% to a single % */
sp++;
appendStringInfoChar(&result, *sp);
break;
default:
/* otherwise treat the % as not special */
appendStringInfoChar(&result, *sp);
break;
}
}
else
{
appendStringInfoChar(&result, *sp);
}
}
return result.data;
}
/*-------------------------------------------------------------------------
*
* archive.h
* Common WAL archive routines
*
* Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/common/archive.h
*
*-------------------------------------------------------------------------
*/
#ifndef ARCHIVE_H
#define ARCHIVE_H
extern char *BuildRestoreCommand(const char *restoreCommand,
const char *xlogpath, /* %p */
const char *xlogfname, /* %f */
const char *lastRestartPointFname); /* %r */
#endif /* ARCHIVE_H */
...@@ -120,6 +120,7 @@ sub mkvcbuild ...@@ -120,6 +120,7 @@ sub mkvcbuild
} }
our @pgcommonallfiles = qw( our @pgcommonallfiles = qw(
archive.c
base64.c config_info.c controldata_utils.c d2s.c encnames.c exec.c base64.c config_info.c controldata_utils.c d2s.c encnames.c exec.c
f2s.c file_perm.c hashfn.c ip.c jsonapi.c f2s.c file_perm.c hashfn.c ip.c jsonapi.c
keywords.c kwlookup.c link-canary.c md5.c keywords.c kwlookup.c link-canary.c md5.c
......
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