32
32
#include "utils/memutils.h"
33
33
#include "utils/ps_status.h"
34
34
35
+ typedef struct
36
+ {
37
+ const char * label ;
38
+ bool progress ;
39
+ bool fastcheckpoint ;
40
+ } basebackup_options ;
41
+
42
+
35
43
static int64 sendDir (char * path , int basepathlen , bool sizeonly );
36
44
static void sendFile (char * path , int basepathlen , struct stat * statbuf );
37
45
static void _tarWriteHeader (char * filename , char * linktarget ,
@@ -40,7 +48,8 @@ static void send_int8_string(StringInfoData *buf, int64 intval);
40
48
static void SendBackupHeader (List * tablespaces );
41
49
static void SendBackupDirectory (char * location , char * spcoid );
42
50
static void base_backup_cleanup (int code , Datum arg );
43
- static void perform_base_backup (const char * backup_label , bool progress , DIR * tblspcdir , bool fastcheckpoint );
51
+ static void perform_base_backup (basebackup_options * opt , DIR * tblspcdir );
52
+ static void parse_basebackup_options (List * options , basebackup_options * opt );
44
53
45
54
typedef struct
46
55
{
@@ -67,9 +76,9 @@ base_backup_cleanup(int code, Datum arg)
67
76
* clobbered by longjmp" from stupider versions of gcc.
68
77
*/
69
78
static void
70
- perform_base_backup (const char * backup_label , bool progress , DIR * tblspcdir , bool fastcheckpoint )
79
+ perform_base_backup (basebackup_options * opt , DIR * tblspcdir )
71
80
{
72
- do_pg_start_backup (backup_label , fastcheckpoint );
81
+ do_pg_start_backup (opt -> label , opt -> fastcheckpoint );
73
82
74
83
PG_ENSURE_ERROR_CLEANUP (base_backup_cleanup , (Datum ) 0 );
75
84
{
@@ -81,7 +90,7 @@ perform_base_backup(const char *backup_label, bool progress, DIR *tblspcdir, boo
81
90
82
91
/* Add a node for the base directory */
83
92
ti = palloc0 (sizeof (tablespaceinfo ));
84
- ti -> size = progress ? sendDir ("." , 1 , true) : -1 ;
93
+ ti -> size = opt -> progress ? sendDir ("." , 1 , true) : -1 ;
85
94
tablespaces = lappend (tablespaces , ti );
86
95
87
96
/* Collect information about all tablespaces */
@@ -107,7 +116,7 @@ perform_base_backup(const char *backup_label, bool progress, DIR *tblspcdir, boo
107
116
ti = palloc (sizeof (tablespaceinfo ));
108
117
ti -> oid = pstrdup (de -> d_name );
109
118
ti -> path = pstrdup (linkpath );
110
- ti -> size = progress ? sendDir (linkpath , strlen (linkpath ), true) : -1 ;
119
+ ti -> size = opt -> progress ? sendDir (linkpath , strlen (linkpath ), true) : -1 ;
111
120
tablespaces = lappend (tablespaces , ti );
112
121
}
113
122
@@ -128,18 +137,73 @@ perform_base_backup(const char *backup_label, bool progress, DIR *tblspcdir, boo
128
137
do_pg_stop_backup ();
129
138
}
130
139
140
+ /*
141
+ * Parse the base backup options passed down by the parser
142
+ */
143
+ static void
144
+ parse_basebackup_options (List * options , basebackup_options * opt )
145
+ {
146
+ ListCell * lopt ;
147
+ bool o_label = false;
148
+ bool o_progress = false;
149
+ bool o_fast = false;
150
+
151
+ MemSet (opt , 0 , sizeof (opt ));
152
+ foreach (lopt , options )
153
+ {
154
+ DefElem * defel = (DefElem * ) lfirst (lopt );
155
+
156
+ if (strcmp (defel -> defname , "label" ) == 0 )
157
+ {
158
+ if (o_label )
159
+ ereport (ERROR ,
160
+ (errcode (ERRCODE_SYNTAX_ERROR ),
161
+ errmsg ("duplicate option \"%s\"" , defel -> defname )));
162
+ opt -> label = strVal (defel -> arg );
163
+ o_label = true;
164
+ }
165
+ else if (strcmp (defel -> defname , "progress" ) == 0 )
166
+ {
167
+ if (o_progress )
168
+ ereport (ERROR ,
169
+ (errcode (ERRCODE_SYNTAX_ERROR ),
170
+ errmsg ("duplicate option \"%s\"" , defel -> defname )));
171
+ opt -> progress = true;
172
+ o_progress = true;
173
+ }
174
+ else if (strcmp (defel -> defname , "fast" ) == 0 )
175
+ {
176
+ if (o_fast )
177
+ ereport (ERROR ,
178
+ (errcode (ERRCODE_SYNTAX_ERROR ),
179
+ errmsg ("duplicate option \"%s\"" , defel -> defname )));
180
+ opt -> fastcheckpoint = true;
181
+ o_fast = true;
182
+ }
183
+ else
184
+ elog (ERROR , "option \"%s\" not recognized" ,
185
+ defel -> defname );
186
+ }
187
+ if (opt -> label == NULL )
188
+ opt -> label = "base backup" ;
189
+ }
190
+
191
+
131
192
/*
132
193
* SendBaseBackup() - send a complete base backup.
133
194
*
134
195
* The function will take care of running pg_start_backup() and
135
196
* pg_stop_backup() for the user.
136
197
*/
137
198
void
138
- SendBaseBackup (const char * backup_label , bool progress , bool fastcheckpoint )
199
+ SendBaseBackup (BaseBackupCmd * cmd )
139
200
{
140
201
DIR * dir ;
141
202
MemoryContext backup_context ;
142
203
MemoryContext old_context ;
204
+ basebackup_options opt ;
205
+
206
+ parse_basebackup_options (cmd -> options , & opt );
143
207
144
208
backup_context = AllocSetContextCreate (CurrentMemoryContext ,
145
209
"Streaming base backup context" ,
@@ -150,15 +214,12 @@ SendBaseBackup(const char *backup_label, bool progress, bool fastcheckpoint)
150
214
151
215
WalSndSetState (WALSNDSTATE_BACKUP );
152
216
153
- if (backup_label == NULL )
154
- backup_label = "base backup" ;
155
-
156
217
if (update_process_title )
157
218
{
158
219
char activitymsg [50 ];
159
220
160
221
snprintf (activitymsg , sizeof (activitymsg ), "sending backup \"%s\"" ,
161
- backup_label );
222
+ opt . label );
162
223
set_ps_display (activitymsg , false);
163
224
}
164
225
@@ -168,7 +229,7 @@ SendBaseBackup(const char *backup_label, bool progress, bool fastcheckpoint)
168
229
ereport (ERROR ,
169
230
(errmsg ("unable to open directory pg_tblspc: %m" )));
170
231
171
- perform_base_backup (backup_label , progress , dir , fastcheckpoint );
232
+ perform_base_backup (& opt , dir );
172
233
173
234
FreeDir (dir );
174
235
0 commit comments