1
1
#include "postgres_fe.h"
2
2
3
- #include <fcntl.h>
4
- #include <sys/wait.h>
5
- #include <unistd.h>
6
-
7
3
#include "access/xlog_internal.h"
8
4
#include "access/xlog_smgr.h"
9
5
#include "common/logging.h"
6
+ #include "common/percentrepl.h"
10
7
11
8
#include "access/pg_tde_fe_init.h"
12
9
#include "access/pg_tde_xlog_smgr.h"
@@ -116,26 +113,39 @@ write_decrypted_segment(const char *segpath, const char *segname, const char *tm
116
113
static void
117
114
usage (const char * progname )
118
115
{
119
- 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 );
121
- printf (_ ("Options:\n" ));
122
- printf (_ (" -V, --version output version information, then exit\n" ));
123
- printf (_ (" -?, --help show this help, then exit\n" ));
116
+ printf (_ ("%s wraps an archive command to give the command unencrypted WAL.\n\n" ), progname );
117
+ printf (_ ("Usage:\n" ));
118
+ printf (_ (" %s [OPTION]\n" ), progname );
119
+ printf (_ (" %s DEST-NAME SOURCE-PATH ARCHIVE-COMMAND\n" ), progname );
120
+ printf (_ ("\nOptions:\n" ));
121
+ printf (_ (" -V, --version output version information, then exit\n" ));
122
+ printf (_ (" -?, --help show this help, then exit\n" ));
123
+ printf (_ (" DEST-NAME name of the WAL file to send to archive\n" ));
124
+ printf (_ (" SOURCE-PATH path of the source WAL segment to decrypt\n" ));
125
+ printf (_ (" ARCHIVE-COMMAND archive command to wrap, %%p will be replaced with the\n"
126
+ " absolute path of the decrypted WAL segment, %%f with the name\n" ));
127
+ printf (_ ("\n" ));
128
+ printf (_ ("Note that any %%f or %%p parameter in ARCHIVE-COMMAND will have to be escaped\n"
129
+ "as %%%%f or %%%%p respectively if used as archive_command in postgresql.conf.\n"
130
+ "e.g.\n"
131
+ " archive_command='%s %%f %%p \"cp %%%%p /mnt/server/archivedir/%%%%f\"'\n"
132
+ "or\n"
133
+ " archive_command='%s %%f %%p \"pgbackrest --stanza=your_stanza archive-push %%%%p\"'\n"
134
+ "\n" ), progname , progname );
124
135
}
125
136
126
137
int
127
138
main (int argc , char * argv [])
128
139
{
129
140
const char * progname ;
141
+ char * targetname ;
130
142
char * sourcepath ;
143
+ char * command ;
131
144
char * sep ;
132
145
char * sourcename ;
133
146
char tmpdir [MAXPGPATH ] = TMPFS_DIRECTORY "/pg_tde_archiveXXXXXX" ;
134
147
char tmppath [MAXPGPATH ];
135
148
bool issegment ;
136
- pid_t child ;
137
- int status ;
138
- int r ;
139
149
140
150
pg_logging_init (argv [0 ]);
141
151
progname = get_progname (argv [0 ]);
@@ -154,14 +164,16 @@ main(int argc, char *argv[])
154
164
}
155
165
}
156
166
157
- if (argc < 3 )
167
+ if (argc != 4 )
158
168
{
159
- pg_log_error ("too few arguments" );
169
+ pg_log_error ("wrong number of arguments, 3 expected " );
160
170
pg_log_error_detail ("Try \"%s --help\" for more information." , progname );
161
171
exit (1 );
162
172
}
163
173
164
- sourcepath = argv [1 ];
174
+ targetname = argv [1 ];
175
+ sourcepath = argv [2 ];
176
+ command = argv [3 ];
165
177
166
178
pg_tde_fe_init ("pg_tde" );
167
179
TDEXLogSmgrInit ();
@@ -173,7 +185,7 @@ main(int argc, char *argv[])
173
185
else
174
186
sourcename = sourcepath ;
175
187
176
- issegment = is_segment (sourcename );
188
+ issegment = is_segment (targetname );
177
189
178
190
if (issegment )
179
191
{
@@ -186,35 +198,19 @@ main(int argc, char *argv[])
186
198
s = stpcpy (s , "/" );
187
199
stpcpy (s , sourcename );
188
200
189
- for (int i = 2 ; i < argc ; i ++ )
190
- if (strcmp (sourcepath , argv [i ]) == 0 )
191
- argv [i ] = tmppath ;
192
-
193
- write_decrypted_segment (sourcepath , sourcename , tmppath );
194
- }
201
+ command = replace_percent_placeholders (command ,
202
+ "ARCHIVE-COMMAND" , "fp" ,
203
+ targetname , tmppath );
195
204
196
- child = fork ();
197
- if (child == 0 )
198
- {
199
- if (execvp (argv [2 ], argv + 2 ) < 0 )
200
- pg_fatal ("exec failed: %m" );
205
+ write_decrypted_segment (sourcepath , targetname , tmppath );
201
206
}
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 );
207
+ else
208
+ command = replace_percent_placeholders (command ,
209
+ "ARCHIVE-COMMAND" , "fp" ,
210
+ targetname , sourcepath );
213
211
214
- pg_fatal ("%s" , reason );
215
- /* keep lsan happy */
216
- free (reason );
217
- }
212
+ if (system (command ) != 0 )
213
+ pg_fatal ("ARCHIVE-COMMAND \"%s\" failed: %m" , command );
218
214
219
215
if (issegment )
220
216
{
0 commit comments