3232#include "utils/memutils.h"
3333#include "utils/ps_status.h"
3434
35+ typedef struct
36+ {
37+ const char * label ;
38+ bool progress ;
39+ bool fastcheckpoint ;
40+ } basebackup_options ;
41+
42+
3543static int64 sendDir (char * path , int basepathlen , bool sizeonly );
3644static void sendFile (char * path , int basepathlen , struct stat * statbuf );
3745static void _tarWriteHeader (char * filename , char * linktarget ,
@@ -40,7 +48,8 @@ static void send_int8_string(StringInfoData *buf, int64 intval);
4048static void SendBackupHeader (List * tablespaces );
4149static void SendBackupDirectory (char * location , char * spcoid );
4250static 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 );
4453
4554typedef struct
4655{
@@ -67,9 +76,9 @@ base_backup_cleanup(int code, Datum arg)
6776 * clobbered by longjmp" from stupider versions of gcc.
6877 */
6978static void
70- perform_base_backup (const char * backup_label , bool progress , DIR * tblspcdir , bool fastcheckpoint )
79+ perform_base_backup (basebackup_options * opt , DIR * tblspcdir )
7180{
72- do_pg_start_backup (backup_label , fastcheckpoint );
81+ do_pg_start_backup (opt -> label , opt -> fastcheckpoint );
7382
7483 PG_ENSURE_ERROR_CLEANUP (base_backup_cleanup , (Datum ) 0 );
7584 {
@@ -81,7 +90,7 @@ perform_base_backup(const char *backup_label, bool progress, DIR *tblspcdir, boo
8190
8291 /* Add a node for the base directory */
8392 ti = palloc0 (sizeof (tablespaceinfo ));
84- ti -> size = progress ? sendDir ("." , 1 , true) : -1 ;
93+ ti -> size = opt -> progress ? sendDir ("." , 1 , true) : -1 ;
8594 tablespaces = lappend (tablespaces , ti );
8695
8796 /* Collect information about all tablespaces */
@@ -107,7 +116,7 @@ perform_base_backup(const char *backup_label, bool progress, DIR *tblspcdir, boo
107116 ti = palloc (sizeof (tablespaceinfo ));
108117 ti -> oid = pstrdup (de -> d_name );
109118 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 ;
111120 tablespaces = lappend (tablespaces , ti );
112121 }
113122
@@ -128,18 +137,73 @@ perform_base_backup(const char *backup_label, bool progress, DIR *tblspcdir, boo
128137 do_pg_stop_backup ();
129138}
130139
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+
131192/*
132193 * SendBaseBackup() - send a complete base backup.
133194 *
134195 * The function will take care of running pg_start_backup() and
135196 * pg_stop_backup() for the user.
136197 */
137198void
138- SendBaseBackup (const char * backup_label , bool progress , bool fastcheckpoint )
199+ SendBaseBackup (BaseBackupCmd * cmd )
139200{
140201 DIR * dir ;
141202 MemoryContext backup_context ;
142203 MemoryContext old_context ;
204+ basebackup_options opt ;
205+
206+ parse_basebackup_options (cmd -> options , & opt );
143207
144208 backup_context = AllocSetContextCreate (CurrentMemoryContext ,
145209 "Streaming base backup context" ,
@@ -150,15 +214,12 @@ SendBaseBackup(const char *backup_label, bool progress, bool fastcheckpoint)
150214
151215 WalSndSetState (WALSNDSTATE_BACKUP );
152216
153- if (backup_label == NULL )
154- backup_label = "base backup" ;
155-
156217 if (update_process_title )
157218 {
158219 char activitymsg [50 ];
159220
160221 snprintf (activitymsg , sizeof (activitymsg ), "sending backup \"%s\"" ,
161- backup_label );
222+ opt . label );
162223 set_ps_display (activitymsg , false);
163224 }
164225
@@ -168,7 +229,7 @@ SendBaseBackup(const char *backup_label, bool progress, bool fastcheckpoint)
168229 ereport (ERROR ,
169230 (errmsg ("unable to open directory pg_tblspc: %m" )));
170231
171- perform_base_backup (backup_label , progress , dir , fastcheckpoint );
232+ perform_base_backup (& opt , dir );
172233
173234 FreeDir (dir );
174235
0 commit comments