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
7483PG_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 */
8392ti = palloc0 (sizeof (tablespaceinfo ));
84- ti -> size = progress ?sendDir ("." ,1 , true) :-1 ;
93+ ti -> size = opt -> progress ?sendDir ("." ,1 , true) :-1 ;
8594tablespaces = 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
107116ti = palloc (sizeof (tablespaceinfo ));
108117ti -> oid = pstrdup (de -> d_name );
109118ti -> path = pstrdup (linkpath );
110- ti -> size = progress ?sendDir (linkpath ,strlen (linkpath ), true) :-1 ;
119+ ti -> size = opt -> progress ?sendDir (linkpath ,strlen (linkpath ), true) :-1 ;
111120tablespaces = lappend (tablespaces ,ti );
112121}
113122
@@ -128,18 +137,73 @@ perform_base_backup(const char *backup_label, bool progress, DIR *tblspcdir, boo
128137do_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{
140201DIR * dir ;
141202MemoryContext backup_context ;
142203MemoryContext old_context ;
204+ basebackup_options opt ;
205+
206+ parse_basebackup_options (cmd -> options ,& opt );
143207
144208backup_context = AllocSetContextCreate (CurrentMemoryContext ,
145209"Streaming base backup context" ,
@@ -150,15 +214,12 @@ SendBaseBackup(const char *backup_label, bool progress, bool fastcheckpoint)
150214
151215WalSndSetState (WALSNDSTATE_BACKUP );
152216
153- if (backup_label == NULL )
154- backup_label = "base backup" ;
155-
156217if (update_process_title )
157218{
158219char activitymsg [50 ];
159220
160221snprintf (activitymsg ,sizeof (activitymsg ),"sending backup \"%s\"" ,
161- backup_label );
222+ opt . label );
162223set_ps_display (activitymsg , false);
163224}
164225
@@ -168,7 +229,7 @@ SendBaseBackup(const char *backup_label, bool progress, bool fastcheckpoint)
168229ereport (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
173234FreeDir (dir );
174235