Skip to content

Commit 0a9344d

Browse files
committed
PoC: Use system() instead of exec*() for our archive and restore commands
Instead of using exec() and replacing the path where we find a while argument match the path we use system() with another layer of placeholders.
1 parent 458e6ed commit 0a9344d

File tree

3 files changed

+28
-68
lines changed

3 files changed

+28
-68
lines changed

contrib/pg_tde/src/bin/pg_tde_archive_decrypt.c

Lines changed: 13 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
#include "postgres_fe.h"
22

3-
#include <fcntl.h>
4-
#include <sys/wait.h>
5-
#include <unistd.h>
6-
73
#include "access/xlog_internal.h"
84
#include "access/xlog_smgr.h"
95
#include "common/logging.h"
6+
#include "common/percentrepl.h"
107

118
#include "access/pg_tde_fe_init.h"
129
#include "access/pg_tde_xlog_smgr.h"
@@ -117,7 +114,7 @@ static void
117114
usage(const char *progname)
118115
{
119116
printf(_("%s wraps an archive command to make it archive unencrypted WAL.\n\n"), progname);
120-
printf(_("Usage:\n %s %%p <archive command>\n\n"), progname);
117+
printf(_("Usage:\n %s %%p ARCHIVE_COMMAND\n\n"), progname);
121118
printf(_("Options:\n"));
122119
printf(_(" -V, --version output version information, then exit\n"));
123120
printf(_(" -?, --help show this help, then exit\n"));
@@ -128,14 +125,12 @@ main(int argc, char *argv[])
128125
{
129126
const char *progname;
130127
char *sourcepath;
128+
char *command;
131129
char *sep;
132130
char *sourcename;
133131
char tmpdir[MAXPGPATH] = TMPFS_DIRECTORY "/pg_tde_archiveXXXXXX";
134132
char tmppath[MAXPGPATH];
135133
bool issegment;
136-
pid_t child;
137-
int status;
138-
int r;
139134

140135
pg_logging_init(argv[0]);
141136
progname = get_progname(argv[0]);
@@ -162,6 +157,7 @@ main(int argc, char *argv[])
162157
}
163158

164159
sourcepath = argv[1];
160+
command = argv[2];
165161

166162
pg_tde_fe_init("pg_tde");
167163
TDEXLogSmgrInit();
@@ -186,35 +182,19 @@ main(int argc, char *argv[])
186182
s = stpcpy(s, "/");
187183
stpcpy(s, sourcename);
188184

189-
for (int i = 2; i < argc; i++)
190-
if (strcmp(sourcepath, argv[i]) == 0)
191-
argv[i] = tmppath;
185+
command = replace_percent_placeholders(command,
186+
"archive_command", "fp",
187+
sourcename, tmppath);
192188

193189
write_decrypted_segment(sourcepath, sourcename, tmppath);
194190
}
191+
else
192+
command = replace_percent_placeholders(command,
193+
"archive_command", "fp",
194+
sourcename, sourcepath);
195195

196-
child = fork();
197-
if (child == 0)
198-
{
199-
if (execvp(argv[2], argv + 2) < 0)
200-
pg_fatal("exec failed: %m");
201-
}
202-
else if (child < 0)
203-
pg_fatal("could not create background process: %m");
204-
205-
r = waitpid(child, &status, 0);
206-
if (r == (pid_t) -1)
207-
pg_fatal("could not wait for child process: %m");
208-
if (r != child)
209-
pg_fatal("child %d died, expected %d", (int) r, (int) child);
210-
if (status != 0)
211-
{
212-
char *reason = wait_result_to_str(status);
213-
214-
pg_fatal("%s", reason);
215-
/* keep lsan happy */
216-
free(reason);
217-
}
196+
if (system(command) != 0)
197+
pg_fatal("system failed: %m");
218198

219199
if (issegment)
220200
{

contrib/pg_tde/src/bin/pg_tde_restore_encrypt.c

Lines changed: 13 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
#include "postgres_fe.h"
22

3-
#include <fcntl.h>
4-
#include <sys/wait.h>
5-
#include <unistd.h>
6-
73
#include "access/xlog_internal.h"
84
#include "access/xlog_smgr.h"
95
#include "common/logging.h"
6+
#include "common/percentrepl.h"
107

118
#include "access/pg_tde_fe_init.h"
129
#include "access/pg_tde_xlog_smgr.h"
@@ -111,7 +108,7 @@ static void
111108
usage(const char *progname)
112109
{
113110
printf(_("%s wraps a restore command to make it write encrypted WAL to pg_wal.\n\n"), progname);
114-
printf(_("Usage:\n %s %%f %%p <restore command>\n\n"), progname);
111+
printf(_("Usage:\n %s %%f %%p RESTORE_COMMAND\n\n"), progname);
115112
printf(_("Options:\n"));
116113
printf(_(" -V, --version output version information, then exit\n"));
117114
printf(_(" -?, --help show this help, then exit\n"));
@@ -122,15 +119,13 @@ main(int argc, char *argv[])
122119
{
123120
const char *progname;
124121
char *sourcename;
122+
char *command;
125123
char *targetpath;
126124
char *sep;
127125
char *targetname;
128126
char tmpdir[MAXPGPATH] = TMPFS_DIRECTORY "/pg_tde_restoreXXXXXX";
129127
char tmppath[MAXPGPATH];
130128
bool issegment;
131-
pid_t child;
132-
int status;
133-
int r;
134129

135130
pg_logging_init(argv[0]);
136131
progname = get_progname(argv[0]);
@@ -158,6 +153,7 @@ main(int argc, char *argv[])
158153

159154
sourcename = argv[1];
160155
targetpath = argv[2];
156+
command = argv[3];
161157

162158
pg_tde_fe_init("pg_tde");
163159
TDEXLogSmgrInit();
@@ -182,33 +178,17 @@ main(int argc, char *argv[])
182178
s = stpcpy(s, "/");
183179
stpcpy(s, targetname);
184180

185-
for (int i = 2; i < argc; i++)
186-
if (strcmp(targetpath, argv[i]) == 0)
187-
argv[i] = tmppath;
188-
}
189-
190-
child = fork();
191-
if (child == 0)
192-
{
193-
if (execvp(argv[3], argv + 3) < 0)
194-
pg_fatal("exec failed: %m");
181+
command = replace_percent_placeholders(command,
182+
"restore_command", "fp",
183+
sourcename, tmppath);
195184
}
196-
else if (child < 0)
197-
pg_fatal("could not create background process: %m");
198-
199-
r = waitpid(child, &status, 0);
200-
if (r == (pid_t) -1)
201-
pg_fatal("could not wait for child process: %m");
202-
if (r != child)
203-
pg_fatal("child %d died, expected %d", (int) r, (int) child);
204-
if (status != 0)
205-
{
206-
char *reason = wait_result_to_str(status);
185+
else
186+
command = replace_percent_placeholders(command,
187+
"restore_command", "fp",
188+
sourcename, targetpath);
207189

208-
pg_fatal("%s", reason);
209-
/* keep lsan happy */
210-
free(reason);
211-
}
190+
if (system(command) != 0)
191+
pg_fatal("system failed: %m");
212192

213193
if (issegment)
214194
{

contrib/pg_tde/t/wal_archiving.pl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
$primary->append_conf('postgresql.conf', "checkpoint_timeout = 1h");
2222
$primary->append_conf('postgresql.conf', "archive_mode = on");
2323
$primary->append_conf('postgresql.conf',
24-
"archive_command = 'pg_tde_archive_decrypt %p cp %p $archive_dir/%f'");
24+
"archive_command = 'pg_tde_archive_decrypt %p \"cp %%p $archive_dir/%%f\"'");
2525
$primary->start;
2626

2727
$primary->safe_psql('postgres', "CREATE EXTENSION pg_tde;");
@@ -75,7 +75,7 @@
7575
my $replica = PostgreSQL::Test::Cluster->new('replica');
7676
$replica->init_from_backup($primary, 'backup');
7777
$replica->append_conf('postgresql.conf',
78-
"restore_command = 'pg_tde_restore_encrypt %f %p cp $archive_dir/%f %p'");
78+
"restore_command = 'pg_tde_restore_encrypt %f %p \"cp $archive_dir/%%f %%p\"'");
7979
$replica->append_conf('postgresql.conf', "recovery_target_action = promote");
8080
$replica->set_recovery_mode;
8181
$replica->start;

0 commit comments

Comments
 (0)