]> granicus.if.org Git - postgresql/blob - src/bin/pg_basebackup/pg_basebackup.c
0470401aea05afff1160256d0770bcd487ba1493
[postgresql] / src / bin / pg_basebackup / pg_basebackup.c
1 /*-------------------------------------------------------------------------
2  *
3  * pg_basebackup.c - receive a base backup using streaming replication protocol
4  *
5  * Author: Magnus Hagander <magnus@hagander.net>
6  *
7  * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
8  *
9  * IDENTIFICATION
10  *                src/bin/pg_basebackup/pg_basebackup.c
11  *-------------------------------------------------------------------------
12  */
13
14 #include "postgres_fe.h"
15
16 #include <unistd.h>
17 #include <dirent.h>
18 #include <sys/stat.h>
19 #include <sys/types.h>
20 #include <sys/wait.h>
21 #include <signal.h>
22 #include <time.h>
23
24 #ifdef HAVE_LIBZ
25 #include <zlib.h>
26 #endif
27
28 #include "getopt_long.h"
29 #include "libpq-fe.h"
30 #include "pqexpbuffer.h"
31 #include "pgtar.h"
32 #include "pgtime.h"
33 #include "receivelog.h"
34 #include "replication/basebackup.h"
35 #include "streamutil.h"
36
37
38 #define atooid(x)  ((Oid) strtoul((x), NULL, 10))
39
40 typedef struct TablespaceListCell
41 {
42         struct TablespaceListCell *next;
43         char            old_dir[MAXPGPATH];
44         char            new_dir[MAXPGPATH];
45 } TablespaceListCell;
46
47 typedef struct TablespaceList
48 {
49         TablespaceListCell *head;
50         TablespaceListCell *tail;
51 } TablespaceList;
52
53 /* Global options */
54 static char *basedir = NULL;
55 static TablespaceList tablespace_dirs = {NULL, NULL};
56 static char *xlog_dir = "";
57 static char format = 'p';               /* p(lain)/t(ar) */
58 static char *label = "pg_basebackup base backup";
59 static bool showprogress = false;
60 static int      verbose = 0;
61 static int      compresslevel = 0;
62 static bool includewal = false;
63 static bool streamwal = false;
64 static bool fastcheckpoint = false;
65 static bool writerecoveryconf = false;
66 static int      standby_message_timeout = 10 * 1000;            /* 10 sec = default */
67 static pg_time_t last_progress_report = 0;
68 static int32 maxrate = 0;               /* no limit by default */
69
70
71 /* Progress counters */
72 static uint64 totalsize;
73 static uint64 totaldone;
74 static int      tablespacecount;
75
76 /* Pipe to communicate with background wal receiver process */
77 #ifndef WIN32
78 static int      bgpipe[2] = {-1, -1};
79 #endif
80
81 /* Handle to child process */
82 static pid_t bgchild = -1;
83
84 /* End position for xlog streaming, empty string if unknown yet */
85 static XLogRecPtr xlogendptr;
86
87 #ifndef WIN32
88 static int      has_xlogendptr = 0;
89 #else
90 static volatile LONG has_xlogendptr = 0;
91 #endif
92
93 /* Contents of recovery.conf to be generated */
94 static PQExpBuffer recoveryconfcontents = NULL;
95
96 /* Function headers */
97 static void usage(void);
98 static void disconnect_and_exit(int code);
99 static void verify_dir_is_empty_or_create(char *dirname);
100 static void progress_report(int tablespacenum, const char *filename, bool force);
101
102 static void ReceiveTarFile(PGconn *conn, PGresult *res, int rownum);
103 static void ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum);
104 static void GenerateRecoveryConf(PGconn *conn);
105 static void WriteRecoveryConf(void);
106 static void BaseBackup(void);
107
108 static bool reached_end_position(XLogRecPtr segendpos, uint32 timeline,
109                                          bool segment_finished);
110
111 static const char *get_tablespace_mapping(const char *dir);
112 static void tablespace_list_append(const char *arg);
113
114
115 static void
116 disconnect_and_exit(int code)
117 {
118         if (conn != NULL)
119                 PQfinish(conn);
120
121 #ifndef WIN32
122
123         /*
124          * On windows, our background thread dies along with the process. But on
125          * Unix, if we have started a subprocess, we want to kill it off so it
126          * doesn't remain running trying to stream data.
127          */
128         if (bgchild > 0)
129                 kill(bgchild, SIGTERM);
130 #endif
131
132         exit(code);
133 }
134
135
136 /*
137  * Split argument into old_dir and new_dir and append to tablespace mapping
138  * list.
139  */
140 static void
141 tablespace_list_append(const char *arg)
142 {
143         TablespaceListCell *cell = (TablespaceListCell *) pg_malloc0(sizeof(TablespaceListCell));
144         char       *dst;
145         char       *dst_ptr;
146         const char *arg_ptr;
147
148         dst_ptr = dst = cell->old_dir;
149         for (arg_ptr = arg; *arg_ptr; arg_ptr++)
150         {
151                 if (dst_ptr - dst >= MAXPGPATH)
152                 {
153                         fprintf(stderr, _("%s: directory name too long\n"), progname);
154                         exit(1);
155                 }
156
157                 if (*arg_ptr == '\\' && *(arg_ptr + 1) == '=')
158                         ;                                       /* skip backslash escaping = */
159                 else if (*arg_ptr == '=' && (arg_ptr == arg || *(arg_ptr - 1) != '\\'))
160                 {
161                         if (*cell->new_dir)
162                         {
163                                 fprintf(stderr, _("%s: multiple \"=\" signs in tablespace mapping\n"), progname);
164                                 exit(1);
165                         }
166                         else
167                                 dst = dst_ptr = cell->new_dir;
168                 }
169                 else
170                         *dst_ptr++ = *arg_ptr;
171         }
172
173         if (!*cell->old_dir || !*cell->new_dir)
174         {
175                 fprintf(stderr,
176                                 _("%s: invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\"\n"),
177                                 progname, arg);
178                 exit(1);
179         }
180
181         /*
182          * This check isn't absolutely necessary.  But all tablespaces are created
183          * with absolute directories, so specifying a non-absolute path here would
184          * just never match, possibly confusing users.  It's also good to be
185          * consistent with the new_dir check.
186          */
187         if (!is_absolute_path(cell->old_dir))
188         {
189                 fprintf(stderr, _("%s: old directory is not an absolute path in tablespace mapping: %s\n"),
190                                 progname, cell->old_dir);
191                 exit(1);
192         }
193
194         if (!is_absolute_path(cell->new_dir))
195         {
196                 fprintf(stderr, _("%s: new directory is not an absolute path in tablespace mapping: %s\n"),
197                                 progname, cell->new_dir);
198                 exit(1);
199         }
200
201         if (tablespace_dirs.tail)
202                 tablespace_dirs.tail->next = cell;
203         else
204                 tablespace_dirs.head = cell;
205         tablespace_dirs.tail = cell;
206 }
207
208
209 #ifdef HAVE_LIBZ
210 static const char *
211 get_gz_error(gzFile gzf)
212 {
213         int                     errnum;
214         const char *errmsg;
215
216         errmsg = gzerror(gzf, &errnum);
217         if (errnum == Z_ERRNO)
218                 return strerror(errno);
219         else
220                 return errmsg;
221 }
222 #endif
223
224 static void
225 usage(void)
226 {
227         printf(_("%s takes a base backup of a running PostgreSQL server.\n\n"),
228                    progname);
229         printf(_("Usage:\n"));
230         printf(_("  %s [OPTION]...\n"), progname);
231         printf(_("\nOptions controlling the output:\n"));
232         printf(_("  -D, --pgdata=DIRECTORY receive base backup into directory\n"));
233         printf(_("  -F, --format=p|t       output format (plain (default), tar)\n"));
234         printf(_("  -r, --max-rate=RATE    maximum transfer rate to transfer data directory\n"
235                          "                         (in kB/s, or use suffix \"k\" or \"M\")\n"));
236         printf(_("  -R, --write-recovery-conf\n"
237                          "                         write recovery.conf after backup\n"));
238         printf(_("  -T, --tablespace-mapping=OLDDIR=NEWDIR\n"
239           "                         relocate tablespace in OLDDIR to NEWDIR\n"));
240         printf(_("  -x, --xlog             include required WAL files in backup (fetch mode)\n"));
241         printf(_("  -X, --xlog-method=fetch|stream\n"
242                          "                         include required WAL files with specified method\n"));
243         printf(_("      --xlogdir=XLOGDIR  location for the transaction log directory\n"));
244         printf(_("  -z, --gzip             compress tar output\n"));
245         printf(_("  -Z, --compress=0-9     compress tar output with given compression level\n"));
246         printf(_("\nGeneral options:\n"));
247         printf(_("  -c, --checkpoint=fast|spread\n"
248                          "                         set fast or spread checkpointing\n"));
249         printf(_("  -l, --label=LABEL      set backup label\n"));
250         printf(_("  -P, --progress         show progress information\n"));
251         printf(_("  -v, --verbose          output verbose messages\n"));
252         printf(_("  -V, --version          output version information, then exit\n"));
253         printf(_("  -?, --help             show this help, then exit\n"));
254         printf(_("\nConnection options:\n"));
255         printf(_("  -d, --dbname=CONNSTR   connection string\n"));
256         printf(_("  -h, --host=HOSTNAME    database server host or socket directory\n"));
257         printf(_("  -p, --port=PORT        database server port number\n"));
258         printf(_("  -s, --status-interval=INTERVAL\n"
259                          "                         time between status packets sent to server (in seconds)\n"));
260         printf(_("  -U, --username=NAME    connect as specified database user\n"));
261         printf(_("  -w, --no-password      never prompt for password\n"));
262         printf(_("  -W, --password         force password prompt (should happen automatically)\n"));
263         printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
264 }
265
266
267 /*
268  * Called in the background process every time data is received.
269  * On Unix, we check to see if there is any data on our pipe
270  * (which would mean we have a stop position), and if it is, check if
271  * it is time to stop.
272  * On Windows, we are in a single process, so we can just check if it's
273  * time to stop.
274  */
275 static bool
276 reached_end_position(XLogRecPtr segendpos, uint32 timeline,
277                                          bool segment_finished)
278 {
279         if (!has_xlogendptr)
280         {
281 #ifndef WIN32
282                 fd_set          fds;
283                 struct timeval tv;
284                 int                     r;
285
286                 /*
287                  * Don't have the end pointer yet - check our pipe to see if it has
288                  * been sent yet.
289                  */
290                 FD_ZERO(&fds);
291                 FD_SET(bgpipe[0], &fds);
292
293                 MemSet(&tv, 0, sizeof(tv));
294
295                 r = select(bgpipe[0] + 1, &fds, NULL, NULL, &tv);
296                 if (r == 1)
297                 {
298                         char            xlogend[64];
299                         uint32          hi,
300                                                 lo;
301
302                         MemSet(xlogend, 0, sizeof(xlogend));
303                         r = read(bgpipe[0], xlogend, sizeof(xlogend) - 1);
304                         if (r < 0)
305                         {
306                                 fprintf(stderr, _("%s: could not read from ready pipe: %s\n"),
307                                                 progname, strerror(errno));
308                                 exit(1);
309                         }
310
311                         if (sscanf(xlogend, "%X/%X", &hi, &lo) != 2)
312                         {
313                                 fprintf(stderr,
314                                   _("%s: could not parse transaction log location \"%s\"\n"),
315                                                 progname, xlogend);
316                                 exit(1);
317                         }
318                         xlogendptr = ((uint64) hi) << 32 | lo;
319                         has_xlogendptr = 1;
320
321                         /*
322                          * Fall through to check if we've reached the point further
323                          * already.
324                          */
325                 }
326                 else
327                 {
328                         /*
329                          * No data received on the pipe means we don't know the end
330                          * position yet - so just say it's not time to stop yet.
331                          */
332                         return false;
333                 }
334 #else
335
336                 /*
337                  * On win32, has_xlogendptr is set by the main thread, so if it's not
338                  * set here, we just go back and wait until it shows up.
339                  */
340                 return false;
341 #endif
342         }
343
344         /*
345          * At this point we have an end pointer, so compare it to the current
346          * position to figure out if it's time to stop.
347          */
348         if (segendpos >= xlogendptr)
349                 return true;
350
351         /*
352          * Have end pointer, but haven't reached it yet - so tell the caller to
353          * keep streaming.
354          */
355         return false;
356 }
357
358 typedef struct
359 {
360         PGconn     *bgconn;
361         XLogRecPtr      startptr;
362         char            xlogdir[MAXPGPATH];
363         char       *sysidentifier;
364         int                     timeline;
365 } logstreamer_param;
366
367 static int
368 LogStreamerMain(logstreamer_param *param)
369 {
370         if (!ReceiveXlogStream(param->bgconn, param->startptr, param->timeline,
371                                                    param->sysidentifier, param->xlogdir,
372                                                    reached_end_position, standby_message_timeout,
373                                                    NULL, false))
374
375                 /*
376                  * Any errors will already have been reported in the function process,
377                  * but we need to tell the parent that we didn't shutdown in a nice
378                  * way.
379                  */
380                 return 1;
381
382         PQfinish(param->bgconn);
383         return 0;
384 }
385
386 /*
387  * Initiate background process for receiving xlog during the backup.
388  * The background stream will use its own database connection so we can
389  * stream the logfile in parallel with the backups.
390  */
391 static void
392 StartLogStreamer(char *startpos, uint32 timeline, char *sysidentifier)
393 {
394         logstreamer_param *param;
395         uint32          hi,
396                                 lo;
397
398         param = pg_malloc0(sizeof(logstreamer_param));
399         param->timeline = timeline;
400         param->sysidentifier = sysidentifier;
401
402         /* Convert the starting position */
403         if (sscanf(startpos, "%X/%X", &hi, &lo) != 2)
404         {
405                 fprintf(stderr,
406                                 _("%s: could not parse transaction log location \"%s\"\n"),
407                                 progname, startpos);
408                 disconnect_and_exit(1);
409         }
410         param->startptr = ((uint64) hi) << 32 | lo;
411         /* Round off to even segment position */
412         param->startptr -= param->startptr % XLOG_SEG_SIZE;
413
414 #ifndef WIN32
415         /* Create our background pipe */
416         if (pipe(bgpipe) < 0)
417         {
418                 fprintf(stderr,
419                                 _("%s: could not create pipe for background process: %s\n"),
420                                 progname, strerror(errno));
421                 disconnect_and_exit(1);
422         }
423 #endif
424
425         /* Get a second connection */
426         param->bgconn = GetConnection();
427         if (!param->bgconn)
428                 /* Error message already written in GetConnection() */
429                 exit(1);
430
431         /*
432          * Always in plain format, so we can write to basedir/pg_xlog. But the
433          * directory entry in the tar file may arrive later, so make sure it's
434          * created before we start.
435          */
436         snprintf(param->xlogdir, sizeof(param->xlogdir), "%s/pg_xlog", basedir);
437         verify_dir_is_empty_or_create(param->xlogdir);
438
439         /*
440          * Start a child process and tell it to start streaming. On Unix, this is
441          * a fork(). On Windows, we create a thread.
442          */
443 #ifndef WIN32
444         bgchild = fork();
445         if (bgchild == 0)
446         {
447                 /* in child process */
448                 exit(LogStreamerMain(param));
449         }
450         else if (bgchild < 0)
451         {
452                 fprintf(stderr, _("%s: could not create background process: %s\n"),
453                                 progname, strerror(errno));
454                 disconnect_and_exit(1);
455         }
456
457         /*
458          * Else we are in the parent process and all is well.
459          */
460 #else                                                   /* WIN32 */
461         bgchild = _beginthreadex(NULL, 0, (void *) LogStreamerMain, param, 0, NULL);
462         if (bgchild == 0)
463         {
464                 fprintf(stderr, _("%s: could not create background thread: %s\n"),
465                                 progname, strerror(errno));
466                 disconnect_and_exit(1);
467         }
468 #endif
469 }
470
471 /*
472  * Verify that the given directory exists and is empty. If it does not
473  * exist, it is created. If it exists but is not empty, an error will
474  * be give and the process ended.
475  */
476 static void
477 verify_dir_is_empty_or_create(char *dirname)
478 {
479         switch (pg_check_dir(dirname))
480         {
481                 case 0:
482
483                         /*
484                          * Does not exist, so create
485                          */
486                         if (pg_mkdir_p(dirname, S_IRWXU) == -1)
487                         {
488                                 fprintf(stderr,
489                                                 _("%s: could not create directory \"%s\": %s\n"),
490                                                 progname, dirname, strerror(errno));
491                                 disconnect_and_exit(1);
492                         }
493                         return;
494                 case 1:
495
496                         /*
497                          * Exists, empty
498                          */
499                         return;
500                 case 2:
501                 case 3:
502                 case 4:
503
504                         /*
505                          * Exists, not empty
506                          */
507                         fprintf(stderr,
508                                         _("%s: directory \"%s\" exists but is not empty\n"),
509                                         progname, dirname);
510                         disconnect_and_exit(1);
511                 case -1:
512
513                         /*
514                          * Access problem
515                          */
516                         fprintf(stderr, _("%s: could not access directory \"%s\": %s\n"),
517                                         progname, dirname, strerror(errno));
518                         disconnect_and_exit(1);
519         }
520 }
521
522
523 /*
524  * Print a progress report based on the global variables. If verbose output
525  * is enabled, also print the current file name.
526  *
527  * Progress report is written at maximum once per second, unless the
528  * force parameter is set to true.
529  */
530 static void
531 progress_report(int tablespacenum, const char *filename, bool force)
532 {
533         int                     percent;
534         char            totaldone_str[32];
535         char            totalsize_str[32];
536         pg_time_t       now;
537
538         if (!showprogress)
539                 return;
540
541         now = time(NULL);
542         if (now == last_progress_report && !force)
543                 return;                                 /* Max once per second */
544
545         last_progress_report = now;
546         percent = totalsize ? (int) ((totaldone / 1024) * 100 / totalsize) : 0;
547
548         /*
549          * Avoid overflowing past 100% or the full size. This may make the total
550          * size number change as we approach the end of the backup (the estimate
551          * will always be wrong if WAL is included), but that's better than having
552          * the done column be bigger than the total.
553          */
554         if (percent > 100)
555                 percent = 100;
556         if (totaldone / 1024 > totalsize)
557                 totalsize = totaldone / 1024;
558
559         /*
560          * Separate step to keep platform-dependent format code out of
561          * translatable strings.  And we only test for INT64_FORMAT availability
562          * in snprintf, not fprintf.
563          */
564         snprintf(totaldone_str, sizeof(totaldone_str), INT64_FORMAT,
565                          totaldone / 1024);
566         snprintf(totalsize_str, sizeof(totalsize_str), INT64_FORMAT, totalsize);
567
568 #define VERBOSE_FILENAME_LENGTH 35
569         if (verbose)
570         {
571                 if (!filename)
572
573                         /*
574                          * No filename given, so clear the status line (used for last
575                          * call)
576                          */
577                         fprintf(stderr,
578                                         ngettext("%*s/%s kB (100%%), %d/%d tablespace %*s",
579                                                          "%*s/%s kB (100%%), %d/%d tablespaces %*s",
580                                                          tablespacecount),
581                                         (int) strlen(totalsize_str),
582                                         totaldone_str, totalsize_str,
583                                         tablespacenum, tablespacecount,
584                                         VERBOSE_FILENAME_LENGTH + 5, "");
585                 else
586                 {
587                         bool            truncate = (strlen(filename) > VERBOSE_FILENAME_LENGTH);
588
589                         fprintf(stderr,
590                                         ngettext("%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)",
591                                                          "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)",
592                                                          tablespacecount),
593                                         (int) strlen(totalsize_str),
594                                         totaldone_str, totalsize_str, percent,
595                                         tablespacenum, tablespacecount,
596                         /* Prefix with "..." if we do leading truncation */
597                                         truncate ? "..." : "",
598                         truncate ? VERBOSE_FILENAME_LENGTH - 3 : VERBOSE_FILENAME_LENGTH,
599                         truncate ? VERBOSE_FILENAME_LENGTH - 3 : VERBOSE_FILENAME_LENGTH,
600                         /* Truncate filename at beginning if it's too long */
601                                         truncate ? filename + strlen(filename) - VERBOSE_FILENAME_LENGTH + 3 : filename);
602                 }
603         }
604         else
605                 fprintf(stderr,
606                                 ngettext("%*s/%s kB (%d%%), %d/%d tablespace",
607                                                  "%*s/%s kB (%d%%), %d/%d tablespaces",
608                                                  tablespacecount),
609                                 (int) strlen(totalsize_str),
610                                 totaldone_str, totalsize_str, percent,
611                                 tablespacenum, tablespacecount);
612
613         fprintf(stderr, "\r");
614 }
615
616 static int32
617 parse_max_rate(char *src)
618 {
619         double          result;
620         char       *after_num;
621         char       *suffix = NULL;
622
623         errno = 0;
624         result = strtod(src, &after_num);
625         if (src == after_num)
626         {
627                 fprintf(stderr,
628                                 _("%s: transfer rate \"%s\" is not a valid value\n"),
629                                 progname, src);
630                 exit(1);
631         }
632         if (errno != 0)
633         {
634                 fprintf(stderr,
635                                 _("%s: invalid transfer rate \"%s\": %s\n"),
636                                 progname, src, strerror(errno));
637                 exit(1);
638         }
639
640         if (result <= 0)
641         {
642                 /*
643                  * Reject obviously wrong values here.
644                  */
645                 fprintf(stderr, _("%s: transfer rate must be greater than zero\n"),
646                                 progname);
647                 exit(1);
648         }
649
650         /*
651          * Evaluate suffix, after skipping over possible whitespace. Lack of
652          * suffix means kilobytes.
653          */
654         while (*after_num != '\0' && isspace((unsigned char) *after_num))
655                 after_num++;
656
657         if (*after_num != '\0')
658         {
659                 suffix = after_num;
660                 if (*after_num == 'k')
661                 {
662                         /* kilobyte is the expected unit. */
663                         after_num++;
664                 }
665                 else if (*after_num == 'M')
666                 {
667                         after_num++;
668                         result *= 1024.0;
669                 }
670         }
671
672         /* The rest can only consist of white space. */
673         while (*after_num != '\0' && isspace((unsigned char) *after_num))
674                 after_num++;
675
676         if (*after_num != '\0')
677         {
678                 fprintf(stderr,
679                                 _("%s: invalid --max-rate unit: \"%s\"\n"),
680                                 progname, suffix);
681                 exit(1);
682         }
683
684         /* Valid integer? */
685         if ((uint64) result != (uint64) ((uint32) result))
686         {
687                 fprintf(stderr,
688                                 _("%s: transfer rate \"%s\" exceeds integer range\n"),
689                                 progname, src);
690                 exit(1);
691         }
692
693         /*
694          * The range is checked on the server side too, but avoid the server
695          * connection if a nonsensical value was passed.
696          */
697         if (result < MAX_RATE_LOWER || result > MAX_RATE_UPPER)
698         {
699                 fprintf(stderr,
700                                 _("%s: transfer rate \"%s\" is out of range\n"),
701                                 progname, src);
702                 exit(1);
703         }
704
705         return (int32) result;
706 }
707
708 /*
709  * Write a piece of tar data
710  */
711 static void
712 writeTarData(
713 #ifdef HAVE_LIBZ
714                          gzFile ztarfile,
715 #endif
716                          FILE *tarfile, char *buf, int r, char *current_file)
717 {
718 #ifdef HAVE_LIBZ
719         if (ztarfile != NULL)
720         {
721                 if (gzwrite(ztarfile, buf, r) != r)
722                 {
723                         fprintf(stderr,
724                                         _("%s: could not write to compressed file \"%s\": %s\n"),
725                                         progname, current_file, get_gz_error(ztarfile));
726                         disconnect_and_exit(1);
727                 }
728         }
729         else
730 #endif
731         {
732                 if (fwrite(buf, r, 1, tarfile) != 1)
733                 {
734                         fprintf(stderr, _("%s: could not write to file \"%s\": %s\n"),
735                                         progname, current_file, strerror(errno));
736                         disconnect_and_exit(1);
737                 }
738         }
739 }
740
741 #ifdef HAVE_LIBZ
742 #define WRITE_TAR_DATA(buf, sz) writeTarData(ztarfile, tarfile, buf, sz, filename)
743 #else
744 #define WRITE_TAR_DATA(buf, sz) writeTarData(tarfile, buf, sz, filename)
745 #endif
746
747 /*
748  * Receive a tar format file from the connection to the server, and write
749  * the data from this file directly into a tar file. If compression is
750  * enabled, the data will be compressed while written to the file.
751  *
752  * The file will be named base.tar[.gz] if it's for the main data directory
753  * or <tablespaceoid>.tar[.gz] if it's for another tablespace.
754  *
755  * No attempt to inspect or validate the contents of the file is done.
756  */
757 static void
758 ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
759 {
760         char            filename[MAXPGPATH];
761         char       *copybuf = NULL;
762         FILE       *tarfile = NULL;
763         char            tarhdr[512];
764         bool            basetablespace = PQgetisnull(res, rownum, 0);
765         bool            in_tarhdr = true;
766         bool            skip_file = false;
767         size_t          tarhdrsz = 0;
768         size_t          filesz = 0;
769
770 #ifdef HAVE_LIBZ
771         gzFile          ztarfile = NULL;
772 #endif
773
774         if (basetablespace)
775         {
776                 /*
777                  * Base tablespaces
778                  */
779                 if (strcmp(basedir, "-") == 0)
780                 {
781 #ifdef HAVE_LIBZ
782                         if (compresslevel != 0)
783                         {
784                                 ztarfile = gzdopen(dup(fileno(stdout)), "wb");
785                                 if (gzsetparams(ztarfile, compresslevel,
786                                                                 Z_DEFAULT_STRATEGY) != Z_OK)
787                                 {
788                                         fprintf(stderr,
789                                                         _("%s: could not set compression level %d: %s\n"),
790                                                         progname, compresslevel, get_gz_error(ztarfile));
791                                         disconnect_and_exit(1);
792                                 }
793                         }
794                         else
795 #endif
796                                 tarfile = stdout;
797                         strcpy(filename, "-");
798                 }
799                 else
800                 {
801 #ifdef HAVE_LIBZ
802                         if (compresslevel != 0)
803                         {
804                                 snprintf(filename, sizeof(filename), "%s/base.tar.gz", basedir);
805                                 ztarfile = gzopen(filename, "wb");
806                                 if (gzsetparams(ztarfile, compresslevel,
807                                                                 Z_DEFAULT_STRATEGY) != Z_OK)
808                                 {
809                                         fprintf(stderr,
810                                                         _("%s: could not set compression level %d: %s\n"),
811                                                         progname, compresslevel, get_gz_error(ztarfile));
812                                         disconnect_and_exit(1);
813                                 }
814                         }
815                         else
816 #endif
817                         {
818                                 snprintf(filename, sizeof(filename), "%s/base.tar", basedir);
819                                 tarfile = fopen(filename, "wb");
820                         }
821                 }
822         }
823         else
824         {
825                 /*
826                  * Specific tablespace
827                  */
828 #ifdef HAVE_LIBZ
829                 if (compresslevel != 0)
830                 {
831                         snprintf(filename, sizeof(filename), "%s/%s.tar.gz", basedir,
832                                          PQgetvalue(res, rownum, 0));
833                         ztarfile = gzopen(filename, "wb");
834                         if (gzsetparams(ztarfile, compresslevel,
835                                                         Z_DEFAULT_STRATEGY) != Z_OK)
836                         {
837                                 fprintf(stderr,
838                                                 _("%s: could not set compression level %d: %s\n"),
839                                                 progname, compresslevel, get_gz_error(ztarfile));
840                                 disconnect_and_exit(1);
841                         }
842                 }
843                 else
844 #endif
845                 {
846                         snprintf(filename, sizeof(filename), "%s/%s.tar", basedir,
847                                          PQgetvalue(res, rownum, 0));
848                         tarfile = fopen(filename, "wb");
849                 }
850         }
851
852 #ifdef HAVE_LIBZ
853         if (compresslevel != 0)
854         {
855                 if (!ztarfile)
856                 {
857                         /* Compression is in use */
858                         fprintf(stderr,
859                                         _("%s: could not create compressed file \"%s\": %s\n"),
860                                         progname, filename, get_gz_error(ztarfile));
861                         disconnect_and_exit(1);
862                 }
863         }
864         else
865 #endif
866         {
867                 /* Either no zlib support, or zlib support but compresslevel = 0 */
868                 if (!tarfile)
869                 {
870                         fprintf(stderr, _("%s: could not create file \"%s\": %s\n"),
871                                         progname, filename, strerror(errno));
872                         disconnect_and_exit(1);
873                 }
874         }
875
876         /*
877          * Get the COPY data stream
878          */
879         res = PQgetResult(conn);
880         if (PQresultStatus(res) != PGRES_COPY_OUT)
881         {
882                 fprintf(stderr, _("%s: could not get COPY data stream: %s"),
883                                 progname, PQerrorMessage(conn));
884                 disconnect_and_exit(1);
885         }
886
887         while (1)
888         {
889                 int                     r;
890
891                 if (copybuf != NULL)
892                 {
893                         PQfreemem(copybuf);
894                         copybuf = NULL;
895                 }
896
897                 r = PQgetCopyData(conn, &copybuf, 0);
898                 if (r == -1)
899                 {
900                         /*
901                          * End of chunk. If requested, and this is the base tablespace,
902                          * write recovery.conf into the tarfile. When done, close the file
903                          * (but not stdout).
904                          *
905                          * Also, write two completely empty blocks at the end of the tar
906                          * file, as required by some tar programs.
907                          */
908                         char            zerobuf[1024];
909
910                         MemSet(zerobuf, 0, sizeof(zerobuf));
911
912                         if (basetablespace && writerecoveryconf)
913                         {
914                                 char            header[512];
915                                 int                     padding;
916
917                                 tarCreateHeader(header, "recovery.conf", NULL,
918                                                                 recoveryconfcontents->len,
919                                                                 0600, 04000, 02000,
920                                                                 time(NULL));
921
922                                 padding = ((recoveryconfcontents->len + 511) & ~511) - recoveryconfcontents->len;
923
924                                 WRITE_TAR_DATA(header, sizeof(header));
925                                 WRITE_TAR_DATA(recoveryconfcontents->data, recoveryconfcontents->len);
926                                 if (padding)
927                                         WRITE_TAR_DATA(zerobuf, padding);
928                         }
929
930                         /* 2 * 512 bytes empty data at end of file */
931                         WRITE_TAR_DATA(zerobuf, sizeof(zerobuf));
932
933 #ifdef HAVE_LIBZ
934                         if (ztarfile != NULL)
935                         {
936                                 if (gzclose(ztarfile) != 0)
937                                 {
938                                         fprintf(stderr,
939                                            _("%s: could not close compressed file \"%s\": %s\n"),
940                                                         progname, filename, get_gz_error(ztarfile));
941                                         disconnect_and_exit(1);
942                                 }
943                         }
944                         else
945 #endif
946                         {
947                                 if (strcmp(basedir, "-") != 0)
948                                 {
949                                         if (fclose(tarfile) != 0)
950                                         {
951                                                 fprintf(stderr,
952                                                                 _("%s: could not close file \"%s\": %s\n"),
953                                                                 progname, filename, strerror(errno));
954                                                 disconnect_and_exit(1);
955                                         }
956                                 }
957                         }
958
959                         break;
960                 }
961                 else if (r == -2)
962                 {
963                         fprintf(stderr, _("%s: could not read COPY data: %s"),
964                                         progname, PQerrorMessage(conn));
965                         disconnect_and_exit(1);
966                 }
967
968                 if (!writerecoveryconf || !basetablespace)
969                 {
970                         /*
971                          * When not writing recovery.conf, or when not working on the base
972                          * tablespace, we never have to look for an existing recovery.conf
973                          * file in the stream.
974                          */
975                         WRITE_TAR_DATA(copybuf, r);
976                 }
977                 else
978                 {
979                         /*
980                          * Look for a recovery.conf in the existing tar stream. If it's
981                          * there, we must skip it so we can later overwrite it with our
982                          * own version of the file.
983                          *
984                          * To do this, we have to process the individual files inside the
985                          * TAR stream. The stream consists of a header and zero or more
986                          * chunks, all 512 bytes long. The stream from the server is
987                          * broken up into smaller pieces, so we have to track the size of
988                          * the files to find the next header structure.
989                          */
990                         int                     rr = r;
991                         int                     pos = 0;
992
993                         while (rr > 0)
994                         {
995                                 if (in_tarhdr)
996                                 {
997                                         /*
998                                          * We're currently reading a header structure inside the
999                                          * TAR stream, i.e. the file metadata.
1000                                          */
1001                                         if (tarhdrsz < 512)
1002                                         {
1003                                                 /*
1004                                                  * Copy the header structure into tarhdr in case the
1005                                                  * header is not aligned to 512 bytes or it's not
1006                                                  * returned in whole by the last PQgetCopyData call.
1007                                                  */
1008                                                 int                     hdrleft;
1009                                                 int                     bytes2copy;
1010
1011                                                 hdrleft = 512 - tarhdrsz;
1012                                                 bytes2copy = (rr > hdrleft ? hdrleft : rr);
1013
1014                                                 memcpy(&tarhdr[tarhdrsz], copybuf + pos, bytes2copy);
1015
1016                                                 rr -= bytes2copy;
1017                                                 pos += bytes2copy;
1018                                                 tarhdrsz += bytes2copy;
1019                                         }
1020                                         else
1021                                         {
1022                                                 /*
1023                                                  * We have the complete header structure in tarhdr,
1024                                                  * look at the file metadata: - the subsequent file
1025                                                  * contents have to be skipped if the filename is
1026                                                  * recovery.conf - find out the size of the file
1027                                                  * padded to the next multiple of 512
1028                                                  */
1029                                                 int                     padding;
1030
1031                                                 skip_file = (strcmp(&tarhdr[0], "recovery.conf") == 0);
1032
1033                                                 sscanf(&tarhdr[124], "%11o", (unsigned int *) &filesz);
1034
1035                                                 padding = ((filesz + 511) & ~511) - filesz;
1036                                                 filesz += padding;
1037
1038                                                 /* Next part is the file, not the header */
1039                                                 in_tarhdr = false;
1040
1041                                                 /*
1042                                                  * If we're not skipping the file, write the tar
1043                                                  * header unmodified.
1044                                                  */
1045                                                 if (!skip_file)
1046                                                         WRITE_TAR_DATA(tarhdr, 512);
1047                                         }
1048                                 }
1049                                 else
1050                                 {
1051                                         /*
1052                                          * We're processing a file's contents.
1053                                          */
1054                                         if (filesz > 0)
1055                                         {
1056                                                 /*
1057                                                  * We still have data to read (and possibly write).
1058                                                  */
1059                                                 int                     bytes2write;
1060
1061                                                 bytes2write = (filesz > rr ? rr : filesz);
1062
1063                                                 if (!skip_file)
1064                                                         WRITE_TAR_DATA(copybuf + pos, bytes2write);
1065
1066                                                 rr -= bytes2write;
1067                                                 pos += bytes2write;
1068                                                 filesz -= bytes2write;
1069                                         }
1070                                         else
1071                                         {
1072                                                 /*
1073                                                  * No more data in the current file, the next piece of
1074                                                  * data (if any) will be a new file header structure.
1075                                                  */
1076                                                 in_tarhdr = true;
1077                                                 skip_file = false;
1078                                                 tarhdrsz = 0;
1079                                                 filesz = 0;
1080                                         }
1081                                 }
1082                         }
1083                 }
1084                 totaldone += r;
1085                 progress_report(rownum, filename, false);
1086         }                                                       /* while (1) */
1087         progress_report(rownum, filename, true);
1088
1089         if (copybuf != NULL)
1090                 PQfreemem(copybuf);
1091 }
1092
1093
1094 /*
1095  * Retrieve tablespace path, either relocated or original depending on whether
1096  * -T was passed or not.
1097  */
1098 static const char *
1099 get_tablespace_mapping(const char *dir)
1100 {
1101         TablespaceListCell *cell;
1102
1103         for (cell = tablespace_dirs.head; cell; cell = cell->next)
1104                 if (strcmp(dir, cell->old_dir) == 0)
1105                         return cell->new_dir;
1106
1107         return dir;
1108 }
1109
1110
1111 /*
1112  * Receive a tar format stream from the connection to the server, and unpack
1113  * the contents of it into a directory. Only files, directories and
1114  * symlinks are supported, no other kinds of special files.
1115  *
1116  * If the data is for the main data directory, it will be restored in the
1117  * specified directory. If it's for another tablespace, it will be restored
1118  * in the original or mapped directory.
1119  */
1120 static void
1121 ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum)
1122 {
1123         char            current_path[MAXPGPATH];
1124         char            filename[MAXPGPATH];
1125         const char *mapped_tblspc_path;
1126         int                     current_len_left;
1127         int                     current_padding = 0;
1128         bool            basetablespace;
1129         char       *copybuf = NULL;
1130         FILE       *file = NULL;
1131
1132         basetablespace = PQgetisnull(res, rownum, 0);
1133         if (basetablespace)
1134                 strlcpy(current_path, basedir, sizeof(current_path));
1135         else
1136                 strlcpy(current_path,
1137                                 get_tablespace_mapping(PQgetvalue(res, rownum, 1)),
1138                                 sizeof(current_path));
1139
1140         /*
1141          * Get the COPY data
1142          */
1143         res = PQgetResult(conn);
1144         if (PQresultStatus(res) != PGRES_COPY_OUT)
1145         {
1146                 fprintf(stderr, _("%s: could not get COPY data stream: %s"),
1147                                 progname, PQerrorMessage(conn));
1148                 disconnect_and_exit(1);
1149         }
1150
1151         while (1)
1152         {
1153                 int                     r;
1154
1155                 if (copybuf != NULL)
1156                 {
1157                         PQfreemem(copybuf);
1158                         copybuf = NULL;
1159                 }
1160
1161                 r = PQgetCopyData(conn, &copybuf, 0);
1162
1163                 if (r == -1)
1164                 {
1165                         /*
1166                          * End of chunk
1167                          */
1168                         if (file)
1169                                 fclose(file);
1170
1171                         break;
1172                 }
1173                 else if (r == -2)
1174                 {
1175                         fprintf(stderr, _("%s: could not read COPY data: %s"),
1176                                         progname, PQerrorMessage(conn));
1177                         disconnect_and_exit(1);
1178                 }
1179
1180                 if (file == NULL)
1181                 {
1182                         int                     filemode;
1183
1184                         /*
1185                          * No current file, so this must be the header for a new file
1186                          */
1187                         if (r != 512)
1188                         {
1189                                 fprintf(stderr, _("%s: invalid tar block header size: %d\n"),
1190                                                 progname, r);
1191                                 disconnect_and_exit(1);
1192                         }
1193                         totaldone += 512;
1194
1195                         if (sscanf(copybuf + 124, "%11o", &current_len_left) != 1)
1196                         {
1197                                 fprintf(stderr, _("%s: could not parse file size\n"),
1198                                                 progname);
1199                                 disconnect_and_exit(1);
1200                         }
1201
1202                         /* Set permissions on the file */
1203                         if (sscanf(&copybuf[100], "%07o ", &filemode) != 1)
1204                         {
1205                                 fprintf(stderr, _("%s: could not parse file mode\n"),
1206                                                 progname);
1207                                 disconnect_and_exit(1);
1208                         }
1209
1210                         /*
1211                          * All files are padded up to 512 bytes
1212                          */
1213                         current_padding =
1214                                 ((current_len_left + 511) & ~511) - current_len_left;
1215
1216                         /*
1217                          * First part of header is zero terminated filename
1218                          */
1219                         snprintf(filename, sizeof(filename), "%s/%s", current_path,
1220                                          copybuf);
1221                         if (filename[strlen(filename) - 1] == '/')
1222                         {
1223                                 /*
1224                                  * Ends in a slash means directory or symlink to directory
1225                                  */
1226                                 if (copybuf[156] == '5')
1227                                 {
1228                                         /*
1229                                          * Directory
1230                                          */
1231                                         filename[strlen(filename) - 1] = '\0';          /* Remove trailing slash */
1232                                         if (mkdir(filename, S_IRWXU) != 0)
1233                                         {
1234                                                 /*
1235                                                  * When streaming WAL, pg_xlog will have been created
1236                                                  * by the wal receiver process. Also, when transaction
1237                                                  * log directory location was specified, pg_xlog has
1238                                                  * already been created as a symbolic link before
1239                                                  * starting the actual backup. So just ignore failure
1240                                                  * on them.
1241                                                  */
1242                                                 if ((!streamwal && (strcmp(xlog_dir, "") == 0))
1243                                                         || strcmp(filename + strlen(filename) - 8, "/pg_xlog") != 0)
1244                                                 {
1245                                                         fprintf(stderr,
1246                                                         _("%s: could not create directory \"%s\": %s\n"),
1247                                                                         progname, filename, strerror(errno));
1248                                                         disconnect_and_exit(1);
1249                                                 }
1250                                         }
1251 #ifndef WIN32
1252                                         if (chmod(filename, (mode_t) filemode))
1253                                                 fprintf(stderr,
1254                                                                 _("%s: could not set permissions on directory \"%s\": %s\n"),
1255                                                                 progname, filename, strerror(errno));
1256 #endif
1257                                 }
1258                                 else if (copybuf[156] == '2')
1259                                 {
1260                                         /*
1261                                          * Symbolic link
1262                                          *
1263                                          * It's most likely a link in pg_tblspc directory, to the
1264                                          * location of a tablespace. Apply any tablespace mapping
1265                                          * given on the command line (--tablespace-mapping).
1266                                          * (We blindly apply the mapping without checking that
1267                                          * the link really is inside pg_tblspc. We don't expect
1268                                          * there to be other symlinks in a data directory, but
1269                                          * if there are, you can call it an undocumented feature
1270                                          * that you can map them too.)
1271                                          */
1272                                         filename[strlen(filename) - 1] = '\0';          /* Remove trailing slash */
1273
1274                                         mapped_tblspc_path = get_tablespace_mapping(&copybuf[157]);
1275                                         if (symlink(mapped_tblspc_path, filename) != 0)
1276                                         {
1277                                                 fprintf(stderr,
1278                                                                 _("%s: could not create symbolic link from \"%s\" to \"%s\": %s\n"),
1279                                                                 progname, filename, mapped_tblspc_path,
1280                                                                 strerror(errno));
1281                                                 disconnect_and_exit(1);
1282                                         }
1283                                 }
1284                                 else
1285                                 {
1286                                         fprintf(stderr,
1287                                                         _("%s: unrecognized link indicator \"%c\"\n"),
1288                                                         progname, copybuf[156]);
1289                                         disconnect_and_exit(1);
1290                                 }
1291                                 continue;               /* directory or link handled */
1292                         }
1293
1294                         /*
1295                          * regular file
1296                          */
1297                         file = fopen(filename, "wb");
1298                         if (!file)
1299                         {
1300                                 fprintf(stderr, _("%s: could not create file \"%s\": %s\n"),
1301                                                 progname, filename, strerror(errno));
1302                                 disconnect_and_exit(1);
1303                         }
1304
1305 #ifndef WIN32
1306                         if (chmod(filename, (mode_t) filemode))
1307                                 fprintf(stderr, _("%s: could not set permissions on file \"%s\": %s\n"),
1308                                                 progname, filename, strerror(errno));
1309 #endif
1310
1311                         if (current_len_left == 0)
1312                         {
1313                                 /*
1314                                  * Done with this file, next one will be a new tar header
1315                                  */
1316                                 fclose(file);
1317                                 file = NULL;
1318                                 continue;
1319                         }
1320                 }                                               /* new file */
1321                 else
1322                 {
1323                         /*
1324                          * Continuing blocks in existing file
1325                          */
1326                         if (current_len_left == 0 && r == current_padding)
1327                         {
1328                                 /*
1329                                  * Received the padding block for this file, ignore it and
1330                                  * close the file, then move on to the next tar header.
1331                                  */
1332                                 fclose(file);
1333                                 file = NULL;
1334                                 totaldone += r;
1335                                 continue;
1336                         }
1337
1338                         if (fwrite(copybuf, r, 1, file) != 1)
1339                         {
1340                                 fprintf(stderr, _("%s: could not write to file \"%s\": %s\n"),
1341                                                 progname, filename, strerror(errno));
1342                                 disconnect_and_exit(1);
1343                         }
1344                         totaldone += r;
1345                         progress_report(rownum, filename, false);
1346
1347                         current_len_left -= r;
1348                         if (current_len_left == 0 && current_padding == 0)
1349                         {
1350                                 /*
1351                                  * Received the last block, and there is no padding to be
1352                                  * expected. Close the file and move on to the next tar
1353                                  * header.
1354                                  */
1355                                 fclose(file);
1356                                 file = NULL;
1357                                 continue;
1358                         }
1359                 }                                               /* continuing data in existing file */
1360         }                                                       /* loop over all data blocks */
1361         progress_report(rownum, filename, true);
1362
1363         if (file != NULL)
1364         {
1365                 fprintf(stderr,
1366                                 _("%s: COPY stream ended before last file was finished\n"),
1367                                 progname);
1368                 disconnect_and_exit(1);
1369         }
1370
1371         if (copybuf != NULL)
1372                 PQfreemem(copybuf);
1373
1374         if (basetablespace && writerecoveryconf)
1375                 WriteRecoveryConf();
1376 }
1377
1378 /*
1379  * Escape a parameter value so that it can be used as part of a libpq
1380  * connection string, e.g. in:
1381  *
1382  * application_name=<value>
1383  *
1384  * The returned string is malloc'd. Return NULL on out-of-memory.
1385  */
1386 static char *
1387 escapeConnectionParameter(const char *src)
1388 {
1389         bool            need_quotes = false;
1390         bool            need_escaping = false;
1391         const char *p;
1392         char       *dstbuf;
1393         char       *dst;
1394
1395         /*
1396          * First check if quoting is needed. Any quote (') or backslash (\)
1397          * characters need to be escaped. Parameters are separated by whitespace,
1398          * so any string containing whitespace characters need to be quoted. An
1399          * empty string is represented by ''.
1400          */
1401         if (strchr(src, '\'') != NULL || strchr(src, '\\') != NULL)
1402                 need_escaping = true;
1403
1404         for (p = src; *p; p++)
1405         {
1406                 if (isspace((unsigned char) *p))
1407                 {
1408                         need_quotes = true;
1409                         break;
1410                 }
1411         }
1412
1413         if (*src == '\0')
1414                 return pg_strdup("''");
1415
1416         if (!need_quotes && !need_escaping)
1417                 return pg_strdup(src);  /* no quoting or escaping needed */
1418
1419         /*
1420          * Allocate a buffer large enough for the worst case that all the source
1421          * characters need to be escaped, plus quotes.
1422          */
1423         dstbuf = pg_malloc(strlen(src) * 2 + 2 + 1);
1424
1425         dst = dstbuf;
1426         if (need_quotes)
1427                 *(dst++) = '\'';
1428         for (; *src; src++)
1429         {
1430                 if (*src == '\'' || *src == '\\')
1431                         *(dst++) = '\\';
1432                 *(dst++) = *src;
1433         }
1434         if (need_quotes)
1435                 *(dst++) = '\'';
1436         *dst = '\0';
1437
1438         return dstbuf;
1439 }
1440
1441 /*
1442  * Escape a string so that it can be used as a value in a key-value pair
1443  * a configuration file.
1444  */
1445 static char *
1446 escape_quotes(const char *src)
1447 {
1448         char       *result = escape_single_quotes_ascii(src);
1449
1450         if (!result)
1451         {
1452                 fprintf(stderr, _("%s: out of memory\n"), progname);
1453                 exit(1);
1454         }
1455         return result;
1456 }
1457
1458 /*
1459  * Create a recovery.conf file in memory using a PQExpBuffer
1460  */
1461 static void
1462 GenerateRecoveryConf(PGconn *conn)
1463 {
1464         PQconninfoOption *connOptions;
1465         PQconninfoOption *option;
1466         PQExpBufferData conninfo_buf;
1467         char       *escaped;
1468
1469         recoveryconfcontents = createPQExpBuffer();
1470         if (!recoveryconfcontents)
1471         {
1472                 fprintf(stderr, _("%s: out of memory\n"), progname);
1473                 disconnect_and_exit(1);
1474         }
1475
1476         connOptions = PQconninfo(conn);
1477         if (connOptions == NULL)
1478         {
1479                 fprintf(stderr, _("%s: out of memory\n"), progname);
1480                 disconnect_and_exit(1);
1481         }
1482
1483         appendPQExpBufferStr(recoveryconfcontents, "standby_mode = 'on'\n");
1484
1485         initPQExpBuffer(&conninfo_buf);
1486         for (option = connOptions; option && option->keyword; option++)
1487         {
1488                 /*
1489                  * Do not emit this setting if: - the setting is "replication",
1490                  * "dbname" or "fallback_application_name", since these would be
1491                  * overridden by the libpqwalreceiver module anyway. - not set or
1492                  * empty.
1493                  */
1494                 if (strcmp(option->keyword, "replication") == 0 ||
1495                         strcmp(option->keyword, "dbname") == 0 ||
1496                         strcmp(option->keyword, "fallback_application_name") == 0 ||
1497                         (option->val == NULL) ||
1498                         (option->val != NULL && option->val[0] == '\0'))
1499                         continue;
1500
1501                 /* Separate key-value pairs with spaces */
1502                 if (conninfo_buf.len != 0)
1503                         appendPQExpBufferStr(&conninfo_buf, " ");
1504
1505                 /*
1506                  * Write "keyword=value" pieces, the value string is escaped and/or
1507                  * quoted if necessary.
1508                  */
1509                 escaped = escapeConnectionParameter(option->val);
1510                 appendPQExpBuffer(&conninfo_buf, "%s=%s", option->keyword, escaped);
1511                 free(escaped);
1512         }
1513
1514         /*
1515          * Escape the connection string, so that it can be put in the config file.
1516          * Note that this is different from the escaping of individual connection
1517          * options above!
1518          */
1519         escaped = escape_quotes(conninfo_buf.data);
1520         appendPQExpBuffer(recoveryconfcontents, "primary_conninfo = '%s'\n", escaped);
1521         free(escaped);
1522
1523         if (PQExpBufferBroken(recoveryconfcontents) ||
1524                 PQExpBufferDataBroken(conninfo_buf))
1525         {
1526                 fprintf(stderr, _("%s: out of memory\n"), progname);
1527                 disconnect_and_exit(1);
1528         }
1529
1530         termPQExpBuffer(&conninfo_buf);
1531
1532         PQconninfoFree(connOptions);
1533 }
1534
1535
1536 /*
1537  * Write a recovery.conf file into the directory specified in basedir,
1538  * with the contents already collected in memory.
1539  */
1540 static void
1541 WriteRecoveryConf(void)
1542 {
1543         char            filename[MAXPGPATH];
1544         FILE       *cf;
1545
1546         sprintf(filename, "%s/recovery.conf", basedir);
1547
1548         cf = fopen(filename, "w");
1549         if (cf == NULL)
1550         {
1551                 fprintf(stderr, _("%s: could not create file \"%s\": %s\n"), progname, filename, strerror(errno));
1552                 disconnect_and_exit(1);
1553         }
1554
1555         if (fwrite(recoveryconfcontents->data, recoveryconfcontents->len, 1, cf) != 1)
1556         {
1557                 fprintf(stderr,
1558                                 _("%s: could not write to file \"%s\": %s\n"),
1559                                 progname, filename, strerror(errno));
1560                 disconnect_and_exit(1);
1561         }
1562
1563         fclose(cf);
1564 }
1565
1566
1567 static void
1568 BaseBackup(void)
1569 {
1570         PGresult   *res;
1571         char       *sysidentifier;
1572         TimeLineID      latesttli;
1573         TimeLineID      starttli;
1574         char       *basebkp;
1575         char            escaped_label[MAXPGPATH];
1576         char       *maxrate_clause = NULL;
1577         int                     i;
1578         char            xlogstart[64];
1579         char            xlogend[64];
1580         int                     minServerMajor,
1581                                 maxServerMajor;
1582         int                     serverMajor;
1583
1584         /*
1585          * Connect in replication mode to the server
1586          */
1587         conn = GetConnection();
1588         if (!conn)
1589                 /* Error message already written in GetConnection() */
1590                 exit(1);
1591
1592         /*
1593          * Check server version. BASE_BACKUP command was introduced in 9.1, so we
1594          * can't work with servers older than 9.1.
1595          */
1596         minServerMajor = 901;
1597         maxServerMajor = PG_VERSION_NUM / 100;
1598         serverMajor = PQserverVersion(conn) / 100;
1599         if (serverMajor < minServerMajor || serverMajor > maxServerMajor)
1600         {
1601                 const char *serverver = PQparameterStatus(conn, "server_version");
1602
1603                 fprintf(stderr, _("%s: incompatible server version %s\n"),
1604                                 progname, serverver ? serverver : "'unknown'");
1605                 disconnect_and_exit(1);
1606         }
1607
1608         /*
1609          * If WAL streaming was requested, also check that the server is new
1610          * enough for that.
1611          */
1612         if (streamwal && !CheckServerVersionForStreaming(conn))
1613         {
1614                 /* Error message already written in CheckServerVersionForStreaming() */
1615                 disconnect_and_exit(1);
1616         }
1617
1618         /*
1619          * Build contents of recovery.conf if requested
1620          */
1621         if (writerecoveryconf)
1622                 GenerateRecoveryConf(conn);
1623
1624         /*
1625          * Run IDENTIFY_SYSTEM so we can get the timeline
1626          */
1627         if (!RunIdentifySystem(conn, &sysidentifier, &latesttli, NULL, NULL))
1628                 disconnect_and_exit(1);
1629
1630         /*
1631          * Start the actual backup
1632          */
1633         PQescapeStringConn(conn, escaped_label, label, sizeof(escaped_label), &i);
1634
1635         if (maxrate > 0)
1636                 maxrate_clause = psprintf("MAX_RATE %u", maxrate);
1637
1638         basebkp =
1639                 psprintf("BASE_BACKUP LABEL '%s' %s %s %s %s %s",
1640                                  escaped_label,
1641                                  showprogress ? "PROGRESS" : "",
1642                                  includewal && !streamwal ? "WAL" : "",
1643                                  fastcheckpoint ? "FAST" : "",
1644                                  includewal ? "NOWAIT" : "",
1645                                  maxrate_clause ? maxrate_clause : "");
1646
1647         if (PQsendQuery(conn, basebkp) == 0)
1648         {
1649                 fprintf(stderr, _("%s: could not send replication command \"%s\": %s"),
1650                                 progname, "BASE_BACKUP", PQerrorMessage(conn));
1651                 disconnect_and_exit(1);
1652         }
1653
1654         /*
1655          * Get the starting xlog position
1656          */
1657         res = PQgetResult(conn);
1658         if (PQresultStatus(res) != PGRES_TUPLES_OK)
1659         {
1660                 fprintf(stderr, _("%s: could not initiate base backup: %s"),
1661                                 progname, PQerrorMessage(conn));
1662                 disconnect_and_exit(1);
1663         }
1664         if (PQntuples(res) != 1)
1665         {
1666                 fprintf(stderr,
1667                                 _("%s: server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields\n"),
1668                                 progname, PQntuples(res), PQnfields(res), 1, 2);
1669                 disconnect_and_exit(1);
1670         }
1671
1672         strlcpy(xlogstart, PQgetvalue(res, 0, 0), sizeof(xlogstart));
1673
1674         /*
1675          * 9.3 and later sends the TLI of the starting point. With older servers,
1676          * assume it's the same as the latest timeline reported by
1677          * IDENTIFY_SYSTEM.
1678          */
1679         if (PQnfields(res) >= 2)
1680                 starttli = atoi(PQgetvalue(res, 0, 1));
1681         else
1682                 starttli = latesttli;
1683         PQclear(res);
1684         MemSet(xlogend, 0, sizeof(xlogend));
1685
1686         if (verbose && includewal)
1687                 fprintf(stderr, _("transaction log start point: %s on timeline %u\n"),
1688                                 xlogstart, starttli);
1689
1690         /*
1691          * Get the header
1692          */
1693         res = PQgetResult(conn);
1694         if (PQresultStatus(res) != PGRES_TUPLES_OK)
1695         {
1696                 fprintf(stderr, _("%s: could not get backup header: %s"),
1697                                 progname, PQerrorMessage(conn));
1698                 disconnect_and_exit(1);
1699         }
1700         if (PQntuples(res) < 1)
1701         {
1702                 fprintf(stderr, _("%s: no data returned from server\n"), progname);
1703                 disconnect_and_exit(1);
1704         }
1705
1706         /*
1707          * Sum up the total size, for progress reporting
1708          */
1709         totalsize = totaldone = 0;
1710         tablespacecount = PQntuples(res);
1711         for (i = 0; i < PQntuples(res); i++)
1712         {
1713                 totalsize += atol(PQgetvalue(res, i, 2));
1714
1715                 /*
1716                  * Verify tablespace directories are empty. Don't bother with the
1717                  * first once since it can be relocated, and it will be checked before
1718                  * we do anything anyway.
1719                  */
1720                 if (format == 'p' && !PQgetisnull(res, i, 1))
1721                 {
1722                         char       *path = (char *) get_tablespace_mapping(PQgetvalue(res, i, 1));
1723
1724                         verify_dir_is_empty_or_create(path);
1725                 }
1726         }
1727
1728         /*
1729          * When writing to stdout, require a single tablespace
1730          */
1731         if (format == 't' && strcmp(basedir, "-") == 0 && PQntuples(res) > 1)
1732         {
1733                 fprintf(stderr,
1734                                 _("%s: can only write single tablespace to stdout, database has %d\n"),
1735                                 progname, PQntuples(res));
1736                 disconnect_and_exit(1);
1737         }
1738
1739         /*
1740          * If we're streaming WAL, start the streaming session before we start
1741          * receiving the actual data chunks.
1742          */
1743         if (streamwal)
1744         {
1745                 if (verbose)
1746                         fprintf(stderr, _("%s: starting background WAL receiver\n"),
1747                                         progname);
1748                 StartLogStreamer(xlogstart, starttli, sysidentifier);
1749         }
1750
1751         /*
1752          * Start receiving chunks
1753          */
1754         for (i = 0; i < PQntuples(res); i++)
1755         {
1756                 if (format == 't')
1757                         ReceiveTarFile(conn, res, i);
1758                 else
1759                         ReceiveAndUnpackTarFile(conn, res, i);
1760         }                                                       /* Loop over all tablespaces */
1761
1762         if (showprogress)
1763         {
1764                 progress_report(PQntuples(res), NULL, true);
1765                 fprintf(stderr, "\n");  /* Need to move to next line */
1766         }
1767
1768         PQclear(res);
1769
1770         /*
1771          * Get the stop position
1772          */
1773         res = PQgetResult(conn);
1774         if (PQresultStatus(res) != PGRES_TUPLES_OK)
1775         {
1776                 fprintf(stderr,
1777                  _("%s: could not get transaction log end position from server: %s"),
1778                                 progname, PQerrorMessage(conn));
1779                 disconnect_and_exit(1);
1780         }
1781         if (PQntuples(res) != 1)
1782         {
1783                 fprintf(stderr,
1784                          _("%s: no transaction log end position returned from server\n"),
1785                                 progname);
1786                 disconnect_and_exit(1);
1787         }
1788         strlcpy(xlogend, PQgetvalue(res, 0, 0), sizeof(xlogend));
1789         if (verbose && includewal)
1790                 fprintf(stderr, "transaction log end point: %s\n", xlogend);
1791         PQclear(res);
1792
1793         res = PQgetResult(conn);
1794         if (PQresultStatus(res) != PGRES_COMMAND_OK)
1795         {
1796                 fprintf(stderr, _("%s: final receive failed: %s"),
1797                                 progname, PQerrorMessage(conn));
1798                 disconnect_and_exit(1);
1799         }
1800
1801         if (bgchild > 0)
1802         {
1803 #ifndef WIN32
1804                 int                     status;
1805                 int                     r;
1806 #else
1807                 DWORD           status;
1808                 uint32          hi,
1809                                         lo;
1810 #endif
1811
1812                 if (verbose)
1813                         fprintf(stderr,
1814                                         _("%s: waiting for background process to finish streaming ...\n"), progname);
1815
1816 #ifndef WIN32
1817                 if (write(bgpipe[1], xlogend, strlen(xlogend)) != strlen(xlogend))
1818                 {
1819                         fprintf(stderr,
1820                                         _("%s: could not send command to background pipe: %s\n"),
1821                                         progname, strerror(errno));
1822                         disconnect_and_exit(1);
1823                 }
1824
1825                 /* Just wait for the background process to exit */
1826                 r = waitpid(bgchild, &status, 0);
1827                 if (r == -1)
1828                 {
1829                         fprintf(stderr, _("%s: could not wait for child process: %s\n"),
1830                                         progname, strerror(errno));
1831                         disconnect_and_exit(1);
1832                 }
1833                 if (r != bgchild)
1834                 {
1835                         fprintf(stderr, _("%s: child %d died, expected %d\n"),
1836                                         progname, r, (int) bgchild);
1837                         disconnect_and_exit(1);
1838                 }
1839                 if (!WIFEXITED(status))
1840                 {
1841                         fprintf(stderr, _("%s: child process did not exit normally\n"),
1842                                         progname);
1843                         disconnect_and_exit(1);
1844                 }
1845                 if (WEXITSTATUS(status) != 0)
1846                 {
1847                         fprintf(stderr, _("%s: child process exited with error %d\n"),
1848                                         progname, WEXITSTATUS(status));
1849                         disconnect_and_exit(1);
1850                 }
1851                 /* Exited normally, we're happy! */
1852 #else                                                   /* WIN32 */
1853
1854                 /*
1855                  * On Windows, since we are in the same process, we can just store the
1856                  * value directly in the variable, and then set the flag that says
1857                  * it's there.
1858                  */
1859                 if (sscanf(xlogend, "%X/%X", &hi, &lo) != 2)
1860                 {
1861                         fprintf(stderr,
1862                                   _("%s: could not parse transaction log location \"%s\"\n"),
1863                                         progname, xlogend);
1864                         disconnect_and_exit(1);
1865                 }
1866                 xlogendptr = ((uint64) hi) << 32 | lo;
1867                 InterlockedIncrement(&has_xlogendptr);
1868
1869                 /* First wait for the thread to exit */
1870                 if (WaitForSingleObjectEx((HANDLE) bgchild, INFINITE, FALSE) !=
1871                         WAIT_OBJECT_0)
1872                 {
1873                         _dosmaperr(GetLastError());
1874                         fprintf(stderr, _("%s: could not wait for child thread: %s\n"),
1875                                         progname, strerror(errno));
1876                         disconnect_and_exit(1);
1877                 }
1878                 if (GetExitCodeThread((HANDLE) bgchild, &status) == 0)
1879                 {
1880                         _dosmaperr(GetLastError());
1881                         fprintf(stderr, _("%s: could not get child thread exit status: %s\n"),
1882                                         progname, strerror(errno));
1883                         disconnect_and_exit(1);
1884                 }
1885                 if (status != 0)
1886                 {
1887                         fprintf(stderr, _("%s: child thread exited with error %u\n"),
1888                                         progname, (unsigned int) status);
1889                         disconnect_and_exit(1);
1890                 }
1891                 /* Exited normally, we're happy */
1892 #endif
1893         }
1894
1895         /* Free the recovery.conf contents */
1896         destroyPQExpBuffer(recoveryconfcontents);
1897
1898         /*
1899          * End of copy data. Final result is already checked inside the loop.
1900          */
1901         PQclear(res);
1902         PQfinish(conn);
1903
1904         if (verbose)
1905                 fprintf(stderr, "%s: base backup completed\n", progname);
1906 }
1907
1908
1909 int
1910 main(int argc, char **argv)
1911 {
1912         static struct option long_options[] = {
1913                 {"help", no_argument, NULL, '?'},
1914                 {"version", no_argument, NULL, 'V'},
1915                 {"pgdata", required_argument, NULL, 'D'},
1916                 {"format", required_argument, NULL, 'F'},
1917                 {"checkpoint", required_argument, NULL, 'c'},
1918                 {"max-rate", required_argument, NULL, 'r'},
1919                 {"write-recovery-conf", no_argument, NULL, 'R'},
1920                 {"tablespace-mapping", required_argument, NULL, 'T'},
1921                 {"xlog", no_argument, NULL, 'x'},
1922                 {"xlog-method", required_argument, NULL, 'X'},
1923                 {"gzip", no_argument, NULL, 'z'},
1924                 {"compress", required_argument, NULL, 'Z'},
1925                 {"label", required_argument, NULL, 'l'},
1926                 {"dbname", required_argument, NULL, 'd'},
1927                 {"host", required_argument, NULL, 'h'},
1928                 {"port", required_argument, NULL, 'p'},
1929                 {"username", required_argument, NULL, 'U'},
1930                 {"no-password", no_argument, NULL, 'w'},
1931                 {"password", no_argument, NULL, 'W'},
1932                 {"status-interval", required_argument, NULL, 's'},
1933                 {"verbose", no_argument, NULL, 'v'},
1934                 {"progress", no_argument, NULL, 'P'},
1935                 {"xlogdir", required_argument, NULL, 1},
1936                 {NULL, 0, NULL, 0}
1937         };
1938         int                     c;
1939
1940         int                     option_index;
1941
1942         progname = get_progname(argv[0]);
1943         set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_basebackup"));
1944
1945         if (argc > 1)
1946         {
1947                 if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
1948                 {
1949                         usage();
1950                         exit(0);
1951                 }
1952                 else if (strcmp(argv[1], "-V") == 0
1953                                  || strcmp(argv[1], "--version") == 0)
1954                 {
1955                         puts("pg_basebackup (PostgreSQL) " PG_VERSION);
1956                         exit(0);
1957                 }
1958         }
1959
1960         while ((c = getopt_long(argc, argv, "D:F:r:RT:xX:l:zZ:d:c:h:p:U:s:wWvP",
1961                                                         long_options, &option_index)) != -1)
1962         {
1963                 switch (c)
1964                 {
1965                         case 'D':
1966                                 basedir = pg_strdup(optarg);
1967                                 break;
1968                         case 'F':
1969                                 if (strcmp(optarg, "p") == 0 || strcmp(optarg, "plain") == 0)
1970                                         format = 'p';
1971                                 else if (strcmp(optarg, "t") == 0 || strcmp(optarg, "tar") == 0)
1972                                         format = 't';
1973                                 else
1974                                 {
1975                                         fprintf(stderr,
1976                                                         _("%s: invalid output format \"%s\", must be \"plain\" or \"tar\"\n"),
1977                                                         progname, optarg);
1978                                         exit(1);
1979                                 }
1980                                 break;
1981                         case 'r':
1982                                 maxrate = parse_max_rate(optarg);
1983                                 break;
1984                         case 'R':
1985                                 writerecoveryconf = true;
1986                                 break;
1987                         case 'T':
1988                                 tablespace_list_append(optarg);
1989                                 break;
1990                         case 'x':
1991                                 if (includewal)
1992                                 {
1993                                         fprintf(stderr,
1994                                          _("%s: cannot specify both --xlog and --xlog-method\n"),
1995                                                         progname);
1996                                         exit(1);
1997                                 }
1998
1999                                 includewal = true;
2000                                 streamwal = false;
2001                                 break;
2002                         case 'X':
2003                                 if (includewal)
2004                                 {
2005                                         fprintf(stderr,
2006                                          _("%s: cannot specify both --xlog and --xlog-method\n"),
2007                                                         progname);
2008                                         exit(1);
2009                                 }
2010
2011                                 includewal = true;
2012                                 if (strcmp(optarg, "f") == 0 ||
2013                                         strcmp(optarg, "fetch") == 0)
2014                                         streamwal = false;
2015                                 else if (strcmp(optarg, "s") == 0 ||
2016                                                  strcmp(optarg, "stream") == 0)
2017                                         streamwal = true;
2018                                 else
2019                                 {
2020                                         fprintf(stderr,
2021                                                         _("%s: invalid xlog-method option \"%s\", must be \"fetch\" or \"stream\"\n"),
2022                                                         progname, optarg);
2023                                         exit(1);
2024                                 }
2025                                 break;
2026                         case 1:
2027                                 xlog_dir = pg_strdup(optarg);
2028                                 break;
2029                         case 'l':
2030                                 label = pg_strdup(optarg);
2031                                 break;
2032                         case 'z':
2033 #ifdef HAVE_LIBZ
2034                                 compresslevel = Z_DEFAULT_COMPRESSION;
2035 #else
2036                                 compresslevel = 1;              /* will be rejected below */
2037 #endif
2038                                 break;
2039                         case 'Z':
2040                                 compresslevel = atoi(optarg);
2041                                 if (compresslevel <= 0 || compresslevel > 9)
2042                                 {
2043                                         fprintf(stderr, _("%s: invalid compression level \"%s\"\n"),
2044                                                         progname, optarg);
2045                                         exit(1);
2046                                 }
2047                                 break;
2048                         case 'c':
2049                                 if (pg_strcasecmp(optarg, "fast") == 0)
2050                                         fastcheckpoint = true;
2051                                 else if (pg_strcasecmp(optarg, "spread") == 0)
2052                                         fastcheckpoint = false;
2053                                 else
2054                                 {
2055                                         fprintf(stderr, _("%s: invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\"\n"),
2056                                                         progname, optarg);
2057                                         exit(1);
2058                                 }
2059                                 break;
2060                         case 'd':
2061                                 connection_string = pg_strdup(optarg);
2062                                 break;
2063                         case 'h':
2064                                 dbhost = pg_strdup(optarg);
2065                                 break;
2066                         case 'p':
2067                                 dbport = pg_strdup(optarg);
2068                                 break;
2069                         case 'U':
2070                                 dbuser = pg_strdup(optarg);
2071                                 break;
2072                         case 'w':
2073                                 dbgetpassword = -1;
2074                                 break;
2075                         case 'W':
2076                                 dbgetpassword = 1;
2077                                 break;
2078                         case 's':
2079                                 standby_message_timeout = atoi(optarg) * 1000;
2080                                 if (standby_message_timeout < 0)
2081                                 {
2082                                         fprintf(stderr, _("%s: invalid status interval \"%s\"\n"),
2083                                                         progname, optarg);
2084                                         exit(1);
2085                                 }
2086                                 break;
2087                         case 'v':
2088                                 verbose++;
2089                                 break;
2090                         case 'P':
2091                                 showprogress = true;
2092                                 break;
2093                         default:
2094
2095                                 /*
2096                                  * getopt_long already emitted a complaint
2097                                  */
2098                                 fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2099                                                 progname);
2100                                 exit(1);
2101                 }
2102         }
2103
2104         /*
2105          * Any non-option arguments?
2106          */
2107         if (optind < argc)
2108         {
2109                 fprintf(stderr,
2110                                 _("%s: too many command-line arguments (first is \"%s\")\n"),
2111                                 progname, argv[optind]);
2112                 fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2113                                 progname);
2114                 exit(1);
2115         }
2116
2117         /*
2118          * Required arguments
2119          */
2120         if (basedir == NULL)
2121         {
2122                 fprintf(stderr, _("%s: no target directory specified\n"), progname);
2123                 fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2124                                 progname);
2125                 exit(1);
2126         }
2127
2128         /*
2129          * Mutually exclusive arguments
2130          */
2131         if (format == 'p' && compresslevel != 0)
2132         {
2133                 fprintf(stderr,
2134                                 _("%s: only tar mode backups can be compressed\n"),
2135                                 progname);
2136                 fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2137                                 progname);
2138                 exit(1);
2139         }
2140
2141         if (format != 'p' && streamwal)
2142         {
2143                 fprintf(stderr,
2144                                 _("%s: WAL streaming can only be used in plain mode\n"),
2145                                 progname);
2146                 fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2147                                 progname);
2148                 exit(1);
2149         }
2150
2151         if (strcmp(xlog_dir, "") != 0)
2152         {
2153                 if (format != 'p')
2154                 {
2155                         fprintf(stderr,
2156                                         _("%s: transaction log directory location can only be specified in plain mode\n"),
2157                                         progname);
2158                         fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2159                                         progname);
2160                         exit(1);
2161                 }
2162
2163                 /* clean up xlog directory name, check it's absolute */
2164                 canonicalize_path(xlog_dir);
2165                 if (!is_absolute_path(xlog_dir))
2166                 {
2167                         fprintf(stderr, _("%s: transaction log directory location must be "
2168                                                           "an absolute path\n"), progname);
2169                         fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2170                                         progname);
2171                         exit(1);
2172                 }
2173         }
2174
2175 #ifndef HAVE_LIBZ
2176         if (compresslevel != 0)
2177         {
2178                 fprintf(stderr,
2179                                 _("%s: this build does not support compression\n"),
2180                                 progname);
2181                 exit(1);
2182         }
2183 #endif
2184
2185         /*
2186          * Verify that the target directory exists, or create it. For plaintext
2187          * backups, always require the directory. For tar backups, require it
2188          * unless we are writing to stdout.
2189          */
2190         if (format == 'p' || strcmp(basedir, "-") != 0)
2191                 verify_dir_is_empty_or_create(basedir);
2192
2193         /* Create transaction log symlink, if required */
2194         if (strcmp(xlog_dir, "") != 0)
2195         {
2196                 char       *linkloc;
2197
2198                 verify_dir_is_empty_or_create(xlog_dir);
2199
2200                 /* form name of the place where the symlink must go */
2201                 linkloc = psprintf("%s/pg_xlog", basedir);
2202
2203 #ifdef HAVE_SYMLINK
2204                 if (symlink(xlog_dir, linkloc) != 0)
2205                 {
2206                         fprintf(stderr, _("%s: could not create symbolic link \"%s\": %s\n"),
2207                                         progname, linkloc, strerror(errno));
2208                         exit(1);
2209                 }
2210 #else
2211                 fprintf(stderr, _("%s: symlinks are not supported on this platform\n"));
2212                 exit(1);
2213 #endif
2214                 free(linkloc);
2215         }
2216
2217         BaseBackup();
2218
2219         return 0;
2220 }