Consistently use "superuser" instead of "super user"
[pgsql.git] / src / bin / initdb / initdb.c
bloba16ad026f32da93a0c22f93cef3d2f589d7dfb7f
1 /*-------------------------------------------------------------------------
3 * initdb --- initialize a PostgreSQL installation
5 * initdb creates (initializes) a PostgreSQL database cluster (site,
6 * instance, installation, whatever). A database cluster is a
7 * collection of PostgreSQL databases all managed by the same server.
9 * To create the database cluster, we create the directory that contains
10 * all its data, create the files that hold the global tables, create
11 * a few other control files for it, and create three databases: the
12 * template databases "template0" and "template1", and a default user
13 * database "postgres".
15 * The template databases are ordinary PostgreSQL databases. template0
16 * is never supposed to change after initdb, whereas template1 can be
17 * changed to add site-local standard data. Either one can be copied
18 * to produce a new database.
20 * For largely-historical reasons, the template1 database is the one built
21 * by the basic bootstrap process. After it is complete, template0 and
22 * the default database, postgres, are made just by copying template1.
24 * To create template1, we run the postgres (backend) program in bootstrap
25 * mode and feed it data from the postgres.bki library file. After this
26 * initial bootstrap phase, some additional stuff is created by normal
27 * SQL commands fed to a standalone backend. Some of those commands are
28 * just embedded into this program (yeah, it's ugly), but larger chunks
29 * are taken from script files.
32 * Note:
33 * The program has some memory leakage - it isn't worth cleaning it up.
35 * This is a C implementation of the previous shell script for setting up a
36 * PostgreSQL cluster location, and should be highly compatible with it.
37 * author of C translation: Andrew Dunstan mailto:andrew@dunslane.net
39 * This code is released under the terms of the PostgreSQL License.
41 * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
42 * Portions Copyright (c) 1994, Regents of the University of California
44 * src/bin/initdb/initdb.c
46 *-------------------------------------------------------------------------
49 #include "postgres_fe.h"
51 #include <dirent.h>
52 #include <fcntl.h>
53 #include <sys/stat.h>
54 #include <unistd.h>
55 #include <signal.h>
56 #include <time.h>
58 #ifdef HAVE_SHM_OPEN
59 #include "sys/mman.h"
60 #endif
62 #include "access/xlog_internal.h"
63 #include "catalog/pg_authid_d.h"
64 #include "catalog/pg_class_d.h" /* pgrminclude ignore */
65 #include "catalog/pg_collation_d.h"
66 #include "common/file_perm.h"
67 #include "common/file_utils.h"
68 #include "common/logging.h"
69 #include "common/restricted_token.h"
70 #include "common/string.h"
71 #include "common/username.h"
72 #include "fe_utils/string_utils.h"
73 #include "getaddrinfo.h"
74 #include "getopt_long.h"
75 #include "mb/pg_wchar.h"
76 #include "miscadmin.h"
79 /* Ideally this would be in a .h file, but it hardly seems worth the trouble */
80 extern const char *select_default_timezone(const char *share_path);
82 static const char *const auth_methods_host[] = {
83 "trust", "reject", "scram-sha-256", "md5", "password", "ident", "radius",
84 #ifdef ENABLE_GSS
85 "gss",
86 #endif
87 #ifdef ENABLE_SSPI
88 "sspi",
89 #endif
90 #ifdef USE_PAM
91 "pam", "pam ",
92 #endif
93 #ifdef USE_BSD_AUTH
94 "bsd",
95 #endif
96 #ifdef USE_LDAP
97 "ldap",
98 #endif
99 #ifdef USE_SSL
100 "cert",
101 #endif
102 NULL
104 static const char *const auth_methods_local[] = {
105 "trust", "reject", "scram-sha-256", "md5", "password", "peer", "radius",
106 #ifdef USE_PAM
107 "pam", "pam ",
108 #endif
109 #ifdef USE_BSD_AUTH
110 "bsd",
111 #endif
112 #ifdef USE_LDAP
113 "ldap",
114 #endif
115 NULL
119 * these values are passed in by makefile defines
121 static char *share_path = NULL;
123 /* values to be obtained from arguments */
124 static char *pg_data = NULL;
125 static char *encoding = NULL;
126 static char *locale = NULL;
127 static char *lc_collate = NULL;
128 static char *lc_ctype = NULL;
129 static char *lc_monetary = NULL;
130 static char *lc_numeric = NULL;
131 static char *lc_time = NULL;
132 static char *lc_messages = NULL;
133 static const char *default_text_search_config = NULL;
134 static char *username = NULL;
135 static bool pwprompt = false;
136 static char *pwfilename = NULL;
137 static char *superuser_password = NULL;
138 static const char *authmethodhost = NULL;
139 static const char *authmethodlocal = NULL;
140 static bool debug = false;
141 static bool noclean = false;
142 static bool noinstructions = false;
143 static bool do_sync = true;
144 static bool sync_only = false;
145 static bool show_setting = false;
146 static bool data_checksums = false;
147 static char *xlog_dir = NULL;
148 static char *str_wal_segment_size_mb = NULL;
149 static int wal_segment_size_mb;
152 /* internal vars */
153 static const char *progname;
154 static int encodingid;
155 static char *bki_file;
156 static char *hba_file;
157 static char *ident_file;
158 static char *conf_file;
159 static char *dictionary_file;
160 static char *info_schema_file;
161 static char *features_file;
162 static char *system_constraints_file;
163 static char *system_functions_file;
164 static char *system_views_file;
165 static bool success = false;
166 static bool made_new_pgdata = false;
167 static bool found_existing_pgdata = false;
168 static bool made_new_xlogdir = false;
169 static bool found_existing_xlogdir = false;
170 static char infoversion[100];
171 static bool caught_signal = false;
172 static bool output_failed = false;
173 static int output_errno = 0;
174 static char *pgdata_native;
176 /* defaults */
177 static int n_connections = 10;
178 static int n_buffers = 50;
179 static const char *dynamic_shared_memory_type = NULL;
180 static const char *default_timezone = NULL;
183 * Warning messages for authentication methods
185 #define AUTHTRUST_WARNING \
186 "# CAUTION: Configuring the system for local \"trust\" authentication\n" \
187 "# allows any local user to connect as any PostgreSQL user, including\n" \
188 "# the database superuser. If you do not trust all your local users,\n" \
189 "# use another authentication method.\n"
190 static bool authwarning = false;
193 * Centralized knowledge of switches to pass to backend
195 * Note: we run the backend with -F (fsync disabled) and then do a single
196 * pass of fsync'ing at the end. This is faster than fsync'ing each step.
198 * Note: in the shell-script version, we also passed PGDATA as a -D switch,
199 * but here it is more convenient to pass it as an environment variable
200 * (no quoting to worry about).
202 static const char *boot_options = "-F";
203 static const char *backend_options = "--single -F -O -j -c search_path=pg_catalog -c exit_on_error=true";
205 /* Additional switches to pass to backend (either boot or standalone) */
206 static char *extra_options = "";
208 static const char *const subdirs[] = {
209 "global",
210 "pg_wal/archive_status",
211 "pg_commit_ts",
212 "pg_dynshmem",
213 "pg_notify",
214 "pg_serial",
215 "pg_snapshots",
216 "pg_subtrans",
217 "pg_twophase",
218 "pg_multixact",
219 "pg_multixact/members",
220 "pg_multixact/offsets",
221 "base",
222 "base/1",
223 "pg_replslot",
224 "pg_tblspc",
225 "pg_stat",
226 "pg_stat_tmp",
227 "pg_xact",
228 "pg_logical",
229 "pg_logical/snapshots",
230 "pg_logical/mappings"
234 /* path to 'initdb' binary directory */
235 static char bin_path[MAXPGPATH];
236 static char backend_exec[MAXPGPATH];
238 static char **replace_token(char **lines,
239 const char *token, const char *replacement);
241 #ifndef HAVE_UNIX_SOCKETS
242 static char **filter_lines_with_token(char **lines, const char *token);
243 #endif
244 static char **readfile(const char *path);
245 static void writefile(char *path, char **lines);
246 static FILE *popen_check(const char *command, const char *mode);
247 static char *get_id(void);
248 static int get_encoding_id(const char *encoding_name);
249 static void set_input(char **dest, const char *filename);
250 static void check_input(char *path);
251 static void write_version_file(const char *extrapath);
252 static void set_null_conf(void);
253 static void test_config_settings(void);
254 static void setup_config(void);
255 static void bootstrap_template1(void);
256 static void setup_auth(FILE *cmdfd);
257 static void get_su_pwd(void);
258 static void setup_depend(FILE *cmdfd);
259 static void setup_run_file(FILE *cmdfd, const char *filename);
260 static void setup_description(FILE *cmdfd);
261 static void setup_collation(FILE *cmdfd);
262 static void setup_privileges(FILE *cmdfd);
263 static void set_info_version(void);
264 static void setup_schema(FILE *cmdfd);
265 static void load_plpgsql(FILE *cmdfd);
266 static void vacuum_db(FILE *cmdfd);
267 static void make_template0(FILE *cmdfd);
268 static void make_postgres(FILE *cmdfd);
269 static void trapsig(int signum);
270 static void check_ok(void);
271 static char *escape_quotes(const char *src);
272 static char *escape_quotes_bki(const char *src);
273 static int locale_date_order(const char *locale);
274 static void check_locale_name(int category, const char *locale,
275 char **canonname);
276 static bool check_locale_encoding(const char *locale, int encoding);
277 static void setlocales(void);
278 static void usage(const char *progname);
279 void setup_pgdata(void);
280 void setup_bin_paths(const char *argv0);
281 void setup_data_file_paths(void);
282 void setup_locale_encoding(void);
283 void setup_signals(void);
284 void setup_text_search(void);
285 void create_data_directory(void);
286 void create_xlog_or_symlink(void);
287 void warn_on_mount_point(int error);
288 void initialize_data_directory(void);
291 * macros for running pipes to postgres
293 #define PG_CMD_DECL char cmd[MAXPGPATH]; FILE *cmdfd
295 #define PG_CMD_OPEN \
296 do { \
297 cmdfd = popen_check(cmd, "w"); \
298 if (cmdfd == NULL) \
299 exit(1); /* message already printed by popen_check */ \
300 } while (0)
302 #define PG_CMD_CLOSE \
303 do { \
304 if (pclose_check(cmdfd)) \
305 exit(1); /* message already printed by pclose_check */ \
306 } while (0)
308 #define PG_CMD_PUTS(line) \
309 do { \
310 if (fputs(line, cmdfd) < 0 || fflush(cmdfd) < 0) \
311 output_failed = true, output_errno = errno; \
312 } while (0)
314 #define PG_CMD_PRINTF(fmt, ...) \
315 do { \
316 if (fprintf(cmdfd, fmt, __VA_ARGS__) < 0 || fflush(cmdfd) < 0) \
317 output_failed = true, output_errno = errno; \
318 } while (0)
321 * Escape single quotes and backslashes, suitably for insertions into
322 * configuration files or SQL E'' strings.
324 static char *
325 escape_quotes(const char *src)
327 char *result = escape_single_quotes_ascii(src);
329 if (!result)
331 pg_log_error("out of memory");
332 exit(1);
334 return result;
338 * Escape a field value to be inserted into the BKI data.
339 * Run the value through escape_quotes (which will be inverted
340 * by the backend's DeescapeQuotedString() function), then wrap
341 * the value in single quotes, even if that isn't strictly necessary.
343 static char *
344 escape_quotes_bki(const char *src)
346 char *result;
347 char *data = escape_quotes(src);
348 char *resultp;
349 char *datap;
351 result = (char *) pg_malloc(strlen(data) + 3);
352 resultp = result;
353 *resultp++ = '\'';
354 for (datap = data; *datap; datap++)
355 *resultp++ = *datap;
356 *resultp++ = '\'';
357 *resultp = '\0';
359 free(data);
360 return result;
364 * make a copy of the array of lines, with token replaced by replacement
365 * the first time it occurs on each line.
367 * This does most of what sed was used for in the shell script, but
368 * doesn't need any regexp stuff.
370 static char **
371 replace_token(char **lines, const char *token, const char *replacement)
373 int numlines = 1;
374 int i;
375 char **result;
376 int toklen,
377 replen,
378 diff;
380 for (i = 0; lines[i]; i++)
381 numlines++;
383 result = (char **) pg_malloc(numlines * sizeof(char *));
385 toklen = strlen(token);
386 replen = strlen(replacement);
387 diff = replen - toklen;
389 for (i = 0; i < numlines; i++)
391 char *where;
392 char *newline;
393 int pre;
395 /* just copy pointer if NULL or no change needed */
396 if (lines[i] == NULL || (where = strstr(lines[i], token)) == NULL)
398 result[i] = lines[i];
399 continue;
402 /* if we get here a change is needed - set up new line */
404 newline = (char *) pg_malloc(strlen(lines[i]) + diff + 1);
406 pre = where - lines[i];
408 memcpy(newline, lines[i], pre);
410 memcpy(newline + pre, replacement, replen);
412 strcpy(newline + pre + replen, lines[i] + pre + toklen);
414 result[i] = newline;
417 return result;
421 * make a copy of lines without any that contain the token
423 * a sort of poor man's grep -v
425 #ifndef HAVE_UNIX_SOCKETS
426 static char **
427 filter_lines_with_token(char **lines, const char *token)
429 int numlines = 1;
430 int i,
431 src,
432 dst;
433 char **result;
435 for (i = 0; lines[i]; i++)
436 numlines++;
438 result = (char **) pg_malloc(numlines * sizeof(char *));
440 for (src = 0, dst = 0; src < numlines; src++)
442 if (lines[src] == NULL || strstr(lines[src], token) == NULL)
443 result[dst++] = lines[src];
446 return result;
448 #endif
451 * get the lines from a text file
453 static char **
454 readfile(const char *path)
456 char **result;
457 FILE *infile;
458 StringInfoData line;
459 int maxlines;
460 int n;
462 if ((infile = fopen(path, "r")) == NULL)
464 pg_log_error("could not open file \"%s\" for reading: %m", path);
465 exit(1);
468 initStringInfo(&line);
470 maxlines = 1024;
471 result = (char **) pg_malloc(maxlines * sizeof(char *));
473 n = 0;
474 while (pg_get_line_buf(infile, &line))
476 /* make sure there will be room for a trailing NULL pointer */
477 if (n >= maxlines - 1)
479 maxlines *= 2;
480 result = (char **) pg_realloc(result, maxlines * sizeof(char *));
483 result[n++] = pg_strdup(line.data);
485 result[n] = NULL;
487 pfree(line.data);
489 fclose(infile);
491 return result;
495 * write an array of lines to a file
497 * This is only used to write text files. Use fopen "w" not PG_BINARY_W
498 * so that the resulting configuration files are nicely editable on Windows.
500 static void
501 writefile(char *path, char **lines)
503 FILE *out_file;
504 char **line;
506 if ((out_file = fopen(path, "w")) == NULL)
508 pg_log_error("could not open file \"%s\" for writing: %m", path);
509 exit(1);
511 for (line = lines; *line != NULL; line++)
513 if (fputs(*line, out_file) < 0)
515 pg_log_error("could not write file \"%s\": %m", path);
516 exit(1);
518 free(*line);
520 if (fclose(out_file))
522 pg_log_error("could not write file \"%s\": %m", path);
523 exit(1);
528 * Open a subcommand with suitable error messaging
530 static FILE *
531 popen_check(const char *command, const char *mode)
533 FILE *cmdfd;
535 fflush(stdout);
536 fflush(stderr);
537 errno = 0;
538 cmdfd = popen(command, mode);
539 if (cmdfd == NULL)
540 pg_log_error("could not execute command \"%s\": %m", command);
541 return cmdfd;
545 * clean up any files we created on failure
546 * if we created the data directory remove it too
548 static void
549 cleanup_directories_atexit(void)
551 if (success)
552 return;
554 if (!noclean)
556 if (made_new_pgdata)
558 pg_log_info("removing data directory \"%s\"", pg_data);
559 if (!rmtree(pg_data, true))
560 pg_log_error("failed to remove data directory");
562 else if (found_existing_pgdata)
564 pg_log_info("removing contents of data directory \"%s\"",
565 pg_data);
566 if (!rmtree(pg_data, false))
567 pg_log_error("failed to remove contents of data directory");
570 if (made_new_xlogdir)
572 pg_log_info("removing WAL directory \"%s\"", xlog_dir);
573 if (!rmtree(xlog_dir, true))
574 pg_log_error("failed to remove WAL directory");
576 else if (found_existing_xlogdir)
578 pg_log_info("removing contents of WAL directory \"%s\"", xlog_dir);
579 if (!rmtree(xlog_dir, false))
580 pg_log_error("failed to remove contents of WAL directory");
582 /* otherwise died during startup, do nothing! */
584 else
586 if (made_new_pgdata || found_existing_pgdata)
587 pg_log_info("data directory \"%s\" not removed at user's request",
588 pg_data);
590 if (made_new_xlogdir || found_existing_xlogdir)
591 pg_log_info("WAL directory \"%s\" not removed at user's request",
592 xlog_dir);
597 * find the current user
599 * on unix make sure it isn't root
601 static char *
602 get_id(void)
604 const char *username;
606 #ifndef WIN32
607 if (geteuid() == 0) /* 0 is root's uid */
609 pg_log_error("cannot be run as root");
610 fprintf(stderr,
611 _("Please log in (using, e.g., \"su\") as the (unprivileged) user that will\n"
612 "own the server process.\n"));
613 exit(1);
615 #endif
617 username = get_user_name_or_exit(progname);
619 return pg_strdup(username);
622 static char *
623 encodingid_to_string(int enc)
625 char result[20];
627 sprintf(result, "%d", enc);
628 return pg_strdup(result);
632 * get the encoding id for a given encoding name
634 static int
635 get_encoding_id(const char *encoding_name)
637 int enc;
639 if (encoding_name && *encoding_name)
641 if ((enc = pg_valid_server_encoding(encoding_name)) >= 0)
642 return enc;
644 pg_log_error("\"%s\" is not a valid server encoding name",
645 encoding_name ? encoding_name : "(null)");
646 exit(1);
650 * Support for determining the best default text search configuration.
651 * We key this off the first part of LC_CTYPE (ie, the language name).
653 struct tsearch_config_match
655 const char *tsconfname;
656 const char *langname;
659 static const struct tsearch_config_match tsearch_config_languages[] =
661 {"arabic", "ar"},
662 {"arabic", "Arabic"},
663 {"armenian", "hy"},
664 {"armenian", "Armenian"},
665 {"basque", "eu"},
666 {"basque", "Basque"},
667 {"catalan", "ca"},
668 {"catalan", "Catalan"},
669 {"danish", "da"},
670 {"danish", "Danish"},
671 {"dutch", "nl"},
672 {"dutch", "Dutch"},
673 {"english", "C"},
674 {"english", "POSIX"},
675 {"english", "en"},
676 {"english", "English"},
677 {"finnish", "fi"},
678 {"finnish", "Finnish"},
679 {"french", "fr"},
680 {"french", "French"},
681 {"german", "de"},
682 {"german", "German"},
683 {"greek", "el"},
684 {"greek", "Greek"},
685 {"hindi", "hi"},
686 {"hindi", "Hindi"},
687 {"hungarian", "hu"},
688 {"hungarian", "Hungarian"},
689 {"indonesian", "id"},
690 {"indonesian", "Indonesian"},
691 {"irish", "ga"},
692 {"irish", "Irish"},
693 {"italian", "it"},
694 {"italian", "Italian"},
695 {"lithuanian", "lt"},
696 {"lithuanian", "Lithuanian"},
697 {"nepali", "ne"},
698 {"nepali", "Nepali"},
699 {"norwegian", "no"},
700 {"norwegian", "Norwegian"},
701 {"portuguese", "pt"},
702 {"portuguese", "Portuguese"},
703 {"romanian", "ro"},
704 {"russian", "ru"},
705 {"russian", "Russian"},
706 {"serbian", "sr"},
707 {"serbian", "Serbian"},
708 {"spanish", "es"},
709 {"spanish", "Spanish"},
710 {"swedish", "sv"},
711 {"swedish", "Swedish"},
712 {"tamil", "ta"},
713 {"tamil", "Tamil"},
714 {"turkish", "tr"},
715 {"turkish", "Turkish"},
716 {"yiddish", "yi"},
717 {"yiddish", "Yiddish"},
718 {NULL, NULL} /* end marker */
722 * Look for a text search configuration matching lc_ctype, and return its
723 * name; return NULL if no match.
725 static const char *
726 find_matching_ts_config(const char *lc_type)
728 int i;
729 char *langname,
730 *ptr;
733 * Convert lc_ctype to a language name by stripping everything after an
734 * underscore (usual case) or a hyphen (Windows "locale name"; see
735 * comments at IsoLocaleName()).
737 * XXX Should ' ' be a stop character? This would select "norwegian" for
738 * the Windows locale "Norwegian (Nynorsk)_Norway.1252". If we do so, we
739 * should also accept the "nn" and "nb" Unix locales.
741 * Just for paranoia, we also stop at '.' or '@'.
743 if (lc_type == NULL)
744 langname = pg_strdup("");
745 else
747 ptr = langname = pg_strdup(lc_type);
748 while (*ptr &&
749 *ptr != '_' && *ptr != '-' && *ptr != '.' && *ptr != '@')
750 ptr++;
751 *ptr = '\0';
754 for (i = 0; tsearch_config_languages[i].tsconfname; i++)
756 if (pg_strcasecmp(tsearch_config_languages[i].langname, langname) == 0)
758 free(langname);
759 return tsearch_config_languages[i].tsconfname;
763 free(langname);
764 return NULL;
769 * set name of given input file variable under data directory
771 static void
772 set_input(char **dest, const char *filename)
774 *dest = psprintf("%s/%s", share_path, filename);
778 * check that given input file exists
780 static void
781 check_input(char *path)
783 struct stat statbuf;
785 if (stat(path, &statbuf) != 0)
787 if (errno == ENOENT)
789 pg_log_error("file \"%s\" does not exist", path);
790 fprintf(stderr,
791 _("This might mean you have a corrupted installation or identified\n"
792 "the wrong directory with the invocation option -L.\n"));
794 else
796 pg_log_error("could not access file \"%s\": %m", path);
797 fprintf(stderr,
798 _("This might mean you have a corrupted installation or identified\n"
799 "the wrong directory with the invocation option -L.\n"));
801 exit(1);
803 if (!S_ISREG(statbuf.st_mode))
805 pg_log_error("file \"%s\" is not a regular file", path);
806 fprintf(stderr,
807 _("This might mean you have a corrupted installation or identified\n"
808 "the wrong directory with the invocation option -L.\n"));
809 exit(1);
814 * write out the PG_VERSION file in the data dir, or its subdirectory
815 * if extrapath is not NULL
817 static void
818 write_version_file(const char *extrapath)
820 FILE *version_file;
821 char *path;
823 if (extrapath == NULL)
824 path = psprintf("%s/PG_VERSION", pg_data);
825 else
826 path = psprintf("%s/%s/PG_VERSION", pg_data, extrapath);
828 if ((version_file = fopen(path, PG_BINARY_W)) == NULL)
830 pg_log_error("could not open file \"%s\" for writing: %m", path);
831 exit(1);
833 if (fprintf(version_file, "%s\n", PG_MAJORVERSION) < 0 ||
834 fclose(version_file))
836 pg_log_error("could not write file \"%s\": %m", path);
837 exit(1);
839 free(path);
843 * set up an empty config file so we can check config settings by launching
844 * a test backend
846 static void
847 set_null_conf(void)
849 FILE *conf_file;
850 char *path;
852 path = psprintf("%s/postgresql.conf", pg_data);
853 conf_file = fopen(path, PG_BINARY_W);
854 if (conf_file == NULL)
856 pg_log_error("could not open file \"%s\" for writing: %m", path);
857 exit(1);
859 if (fclose(conf_file))
861 pg_log_error("could not write file \"%s\": %m", path);
862 exit(1);
864 free(path);
868 * Determine which dynamic shared memory implementation should be used on
869 * this platform. POSIX shared memory is preferable because the default
870 * allocation limits are much higher than the limits for System V on most
871 * systems that support both, but the fact that a platform has shm_open
872 * doesn't guarantee that that call will succeed when attempted. So, we
873 * attempt to reproduce what the postmaster will do when allocating a POSIX
874 * segment in dsm_impl.c; if it doesn't work, we assume it won't work for
875 * the postmaster either, and configure the cluster for System V shared
876 * memory instead.
878 static const char *
879 choose_dsm_implementation(void)
881 #ifdef HAVE_SHM_OPEN
882 int ntries = 10;
884 /* Initialize random(); this function is its only user in this program. */
885 srandom((unsigned int) (getpid() ^ time(NULL)));
887 while (ntries > 0)
889 uint32 handle;
890 char name[64];
891 int fd;
893 handle = random();
894 snprintf(name, 64, "/PostgreSQL.%u", handle);
895 if ((fd = shm_open(name, O_CREAT | O_RDWR | O_EXCL, 0600)) != -1)
897 close(fd);
898 shm_unlink(name);
899 return "posix";
901 if (errno != EEXIST)
902 break;
903 --ntries;
905 #endif
907 #ifdef WIN32
908 return "windows";
909 #else
910 return "sysv";
911 #endif
915 * Determine platform-specific config settings
917 * Use reasonable values if kernel will let us, else scale back.
919 static void
920 test_config_settings(void)
923 * This macro defines the minimum shared_buffers we want for a given
924 * max_connections value. The arrays show the settings to try.
926 #define MIN_BUFS_FOR_CONNS(nconns) ((nconns) * 10)
928 static const int trial_conns[] = {
929 100, 50, 40, 30, 20
931 static const int trial_bufs[] = {
932 16384, 8192, 4096, 3584, 3072, 2560, 2048, 1536,
933 1000, 900, 800, 700, 600, 500,
934 400, 300, 200, 100, 50
937 char cmd[MAXPGPATH];
938 const int connslen = sizeof(trial_conns) / sizeof(int);
939 const int bufslen = sizeof(trial_bufs) / sizeof(int);
940 int i,
941 status,
942 test_conns,
943 test_buffs,
944 ok_buffers = 0;
947 * Need to determine working DSM implementation first so that subsequent
948 * tests don't fail because DSM setting doesn't work.
950 printf(_("selecting dynamic shared memory implementation ... "));
951 fflush(stdout);
952 dynamic_shared_memory_type = choose_dsm_implementation();
953 printf("%s\n", dynamic_shared_memory_type);
956 * Probe for max_connections before shared_buffers, since it is subject to
957 * more constraints than shared_buffers.
959 printf(_("selecting default max_connections ... "));
960 fflush(stdout);
962 for (i = 0; i < connslen; i++)
964 test_conns = trial_conns[i];
965 test_buffs = MIN_BUFS_FOR_CONNS(test_conns);
967 snprintf(cmd, sizeof(cmd),
968 "\"%s\" --check %s %s "
969 "-c max_connections=%d "
970 "-c shared_buffers=%d "
971 "-c dynamic_shared_memory_type=%s "
972 "< \"%s\" > \"%s\" 2>&1",
973 backend_exec, boot_options, extra_options,
974 test_conns, test_buffs,
975 dynamic_shared_memory_type,
976 DEVNULL, DEVNULL);
977 status = system(cmd);
978 if (status == 0)
980 ok_buffers = test_buffs;
981 break;
984 if (i >= connslen)
985 i = connslen - 1;
986 n_connections = trial_conns[i];
988 printf("%d\n", n_connections);
990 printf(_("selecting default shared_buffers ... "));
991 fflush(stdout);
993 for (i = 0; i < bufslen; i++)
995 /* Use same amount of memory, independent of BLCKSZ */
996 test_buffs = (trial_bufs[i] * 8192) / BLCKSZ;
997 if (test_buffs <= ok_buffers)
999 test_buffs = ok_buffers;
1000 break;
1003 snprintf(cmd, sizeof(cmd),
1004 "\"%s\" --check %s %s "
1005 "-c max_connections=%d "
1006 "-c shared_buffers=%d "
1007 "-c dynamic_shared_memory_type=%s "
1008 "< \"%s\" > \"%s\" 2>&1",
1009 backend_exec, boot_options, extra_options,
1010 n_connections, test_buffs,
1011 dynamic_shared_memory_type,
1012 DEVNULL, DEVNULL);
1013 status = system(cmd);
1014 if (status == 0)
1015 break;
1017 n_buffers = test_buffs;
1019 if ((n_buffers * (BLCKSZ / 1024)) % 1024 == 0)
1020 printf("%dMB\n", (n_buffers * (BLCKSZ / 1024)) / 1024);
1021 else
1022 printf("%dkB\n", n_buffers * (BLCKSZ / 1024));
1024 printf(_("selecting default time zone ... "));
1025 fflush(stdout);
1026 default_timezone = select_default_timezone(share_path);
1027 printf("%s\n", default_timezone ? default_timezone : "GMT");
1031 * Calculate the default wal_size with a "pretty" unit.
1033 static char *
1034 pretty_wal_size(int segment_count)
1036 int sz = wal_segment_size_mb * segment_count;
1037 char *result = pg_malloc(14);
1039 if ((sz % 1024) == 0)
1040 snprintf(result, 14, "%dGB", sz / 1024);
1041 else
1042 snprintf(result, 14, "%dMB", sz);
1044 return result;
1048 * set up all the config files
1050 static void
1051 setup_config(void)
1053 char **conflines;
1054 char repltok[MAXPGPATH];
1055 char path[MAXPGPATH];
1056 char *autoconflines[3];
1058 fputs(_("creating configuration files ... "), stdout);
1059 fflush(stdout);
1061 /* postgresql.conf */
1063 conflines = readfile(conf_file);
1065 snprintf(repltok, sizeof(repltok), "max_connections = %d", n_connections);
1066 conflines = replace_token(conflines, "#max_connections = 100", repltok);
1068 if ((n_buffers * (BLCKSZ / 1024)) % 1024 == 0)
1069 snprintf(repltok, sizeof(repltok), "shared_buffers = %dMB",
1070 (n_buffers * (BLCKSZ / 1024)) / 1024);
1071 else
1072 snprintf(repltok, sizeof(repltok), "shared_buffers = %dkB",
1073 n_buffers * (BLCKSZ / 1024));
1074 conflines = replace_token(conflines, "#shared_buffers = 128MB", repltok);
1076 #ifdef HAVE_UNIX_SOCKETS
1077 snprintf(repltok, sizeof(repltok), "#unix_socket_directories = '%s'",
1078 DEFAULT_PGSOCKET_DIR);
1079 #else
1080 snprintf(repltok, sizeof(repltok), "#unix_socket_directories = ''");
1081 #endif
1082 conflines = replace_token(conflines, "#unix_socket_directories = '/tmp'",
1083 repltok);
1085 #if DEF_PGPORT != 5432
1086 snprintf(repltok, sizeof(repltok), "#port = %d", DEF_PGPORT);
1087 conflines = replace_token(conflines, "#port = 5432", repltok);
1088 #endif
1090 /* set default max_wal_size and min_wal_size */
1091 snprintf(repltok, sizeof(repltok), "min_wal_size = %s",
1092 pretty_wal_size(DEFAULT_MIN_WAL_SEGS));
1093 conflines = replace_token(conflines, "#min_wal_size = 80MB", repltok);
1095 snprintf(repltok, sizeof(repltok), "max_wal_size = %s",
1096 pretty_wal_size(DEFAULT_MAX_WAL_SEGS));
1097 conflines = replace_token(conflines, "#max_wal_size = 1GB", repltok);
1099 snprintf(repltok, sizeof(repltok), "lc_messages = '%s'",
1100 escape_quotes(lc_messages));
1101 conflines = replace_token(conflines, "#lc_messages = 'C'", repltok);
1103 snprintf(repltok, sizeof(repltok), "lc_monetary = '%s'",
1104 escape_quotes(lc_monetary));
1105 conflines = replace_token(conflines, "#lc_monetary = 'C'", repltok);
1107 snprintf(repltok, sizeof(repltok), "lc_numeric = '%s'",
1108 escape_quotes(lc_numeric));
1109 conflines = replace_token(conflines, "#lc_numeric = 'C'", repltok);
1111 snprintf(repltok, sizeof(repltok), "lc_time = '%s'",
1112 escape_quotes(lc_time));
1113 conflines = replace_token(conflines, "#lc_time = 'C'", repltok);
1115 switch (locale_date_order(lc_time))
1117 case DATEORDER_YMD:
1118 strcpy(repltok, "datestyle = 'iso, ymd'");
1119 break;
1120 case DATEORDER_DMY:
1121 strcpy(repltok, "datestyle = 'iso, dmy'");
1122 break;
1123 case DATEORDER_MDY:
1124 default:
1125 strcpy(repltok, "datestyle = 'iso, mdy'");
1126 break;
1128 conflines = replace_token(conflines, "#datestyle = 'iso, mdy'", repltok);
1130 snprintf(repltok, sizeof(repltok),
1131 "default_text_search_config = 'pg_catalog.%s'",
1132 escape_quotes(default_text_search_config));
1133 conflines = replace_token(conflines,
1134 "#default_text_search_config = 'pg_catalog.simple'",
1135 repltok);
1137 if (default_timezone)
1139 snprintf(repltok, sizeof(repltok), "timezone = '%s'",
1140 escape_quotes(default_timezone));
1141 conflines = replace_token(conflines, "#timezone = 'GMT'", repltok);
1142 snprintf(repltok, sizeof(repltok), "log_timezone = '%s'",
1143 escape_quotes(default_timezone));
1144 conflines = replace_token(conflines, "#log_timezone = 'GMT'", repltok);
1147 snprintf(repltok, sizeof(repltok), "dynamic_shared_memory_type = %s",
1148 dynamic_shared_memory_type);
1149 conflines = replace_token(conflines, "#dynamic_shared_memory_type = posix",
1150 repltok);
1152 #if DEFAULT_BACKEND_FLUSH_AFTER > 0
1153 snprintf(repltok, sizeof(repltok), "#backend_flush_after = %dkB",
1154 DEFAULT_BACKEND_FLUSH_AFTER * (BLCKSZ / 1024));
1155 conflines = replace_token(conflines, "#backend_flush_after = 0",
1156 repltok);
1157 #endif
1159 #if DEFAULT_BGWRITER_FLUSH_AFTER > 0
1160 snprintf(repltok, sizeof(repltok), "#bgwriter_flush_after = %dkB",
1161 DEFAULT_BGWRITER_FLUSH_AFTER * (BLCKSZ / 1024));
1162 conflines = replace_token(conflines, "#bgwriter_flush_after = 0",
1163 repltok);
1164 #endif
1166 #if DEFAULT_CHECKPOINT_FLUSH_AFTER > 0
1167 snprintf(repltok, sizeof(repltok), "#checkpoint_flush_after = %dkB",
1168 DEFAULT_CHECKPOINT_FLUSH_AFTER * (BLCKSZ / 1024));
1169 conflines = replace_token(conflines, "#checkpoint_flush_after = 0",
1170 repltok);
1171 #endif
1173 #ifndef USE_PREFETCH
1174 conflines = replace_token(conflines,
1175 "#effective_io_concurrency = 1",
1176 "#effective_io_concurrency = 0");
1177 #endif
1179 #ifdef WIN32
1180 conflines = replace_token(conflines,
1181 "#update_process_title = on",
1182 "#update_process_title = off");
1183 #endif
1186 * Change password_encryption setting to md5 if md5 was chosen as an
1187 * authentication method, unless scram-sha-256 was also chosen.
1189 if ((strcmp(authmethodlocal, "md5") == 0 &&
1190 strcmp(authmethodhost, "scram-sha-256") != 0) ||
1191 (strcmp(authmethodhost, "md5") == 0 &&
1192 strcmp(authmethodlocal, "scram-sha-256") != 0))
1194 conflines = replace_token(conflines,
1195 "#password_encryption = scram-sha-256",
1196 "password_encryption = md5");
1200 * If group access has been enabled for the cluster then it makes sense to
1201 * ensure that the log files also allow group access. Otherwise a backup
1202 * from a user in the group would fail if the log files were not
1203 * relocated.
1205 if (pg_dir_create_mode == PG_DIR_MODE_GROUP)
1207 conflines = replace_token(conflines,
1208 "#log_file_mode = 0600",
1209 "log_file_mode = 0640");
1212 snprintf(path, sizeof(path), "%s/postgresql.conf", pg_data);
1214 writefile(path, conflines);
1215 if (chmod(path, pg_file_create_mode) != 0)
1217 pg_log_error("could not change permissions of \"%s\": %m", path);
1218 exit(1);
1222 * create the automatic configuration file to store the configuration
1223 * parameters set by ALTER SYSTEM command. The parameters present in this
1224 * file will override the value of parameters that exists before parse of
1225 * this file.
1227 autoconflines[0] = pg_strdup("# Do not edit this file manually!\n");
1228 autoconflines[1] = pg_strdup("# It will be overwritten by the ALTER SYSTEM command.\n");
1229 autoconflines[2] = NULL;
1231 sprintf(path, "%s/postgresql.auto.conf", pg_data);
1233 writefile(path, autoconflines);
1234 if (chmod(path, pg_file_create_mode) != 0)
1236 pg_log_error("could not change permissions of \"%s\": %m", path);
1237 exit(1);
1240 free(conflines);
1243 /* pg_hba.conf */
1245 conflines = readfile(hba_file);
1247 #ifndef HAVE_UNIX_SOCKETS
1248 conflines = filter_lines_with_token(conflines, "@remove-line-for-nolocal@");
1249 #else
1250 conflines = replace_token(conflines, "@remove-line-for-nolocal@", "");
1251 #endif
1253 #ifdef HAVE_IPV6
1256 * Probe to see if there is really any platform support for IPv6, and
1257 * comment out the relevant pg_hba line if not. This avoids runtime
1258 * warnings if getaddrinfo doesn't actually cope with IPv6. Particularly
1259 * useful on Windows, where executables built on a machine with IPv6 may
1260 * have to run on a machine without.
1263 struct addrinfo *gai_result;
1264 struct addrinfo hints;
1265 int err = 0;
1267 #ifdef WIN32
1268 /* need to call WSAStartup before calling getaddrinfo */
1269 WSADATA wsaData;
1271 err = WSAStartup(MAKEWORD(2, 2), &wsaData);
1272 #endif
1274 /* for best results, this code should match parse_hba_line() */
1275 hints.ai_flags = AI_NUMERICHOST;
1276 hints.ai_family = AF_UNSPEC;
1277 hints.ai_socktype = 0;
1278 hints.ai_protocol = 0;
1279 hints.ai_addrlen = 0;
1280 hints.ai_canonname = NULL;
1281 hints.ai_addr = NULL;
1282 hints.ai_next = NULL;
1284 if (err != 0 ||
1285 getaddrinfo("::1", NULL, &hints, &gai_result) != 0)
1287 conflines = replace_token(conflines,
1288 "host all all ::1",
1289 "#host all all ::1");
1290 conflines = replace_token(conflines,
1291 "host replication all ::1",
1292 "#host replication all ::1");
1295 #else /* !HAVE_IPV6 */
1296 /* If we didn't compile IPV6 support at all, always comment it out */
1297 conflines = replace_token(conflines,
1298 "host all all ::1",
1299 "#host all all ::1");
1300 conflines = replace_token(conflines,
1301 "host replication all ::1",
1302 "#host replication all ::1");
1303 #endif /* HAVE_IPV6 */
1305 /* Replace default authentication methods */
1306 conflines = replace_token(conflines,
1307 "@authmethodhost@",
1308 authmethodhost);
1309 conflines = replace_token(conflines,
1310 "@authmethodlocal@",
1311 authmethodlocal);
1313 conflines = replace_token(conflines,
1314 "@authcomment@",
1315 (strcmp(authmethodlocal, "trust") == 0 || strcmp(authmethodhost, "trust") == 0) ? AUTHTRUST_WARNING : "");
1317 snprintf(path, sizeof(path), "%s/pg_hba.conf", pg_data);
1319 writefile(path, conflines);
1320 if (chmod(path, pg_file_create_mode) != 0)
1322 pg_log_error("could not change permissions of \"%s\": %m", path);
1323 exit(1);
1326 free(conflines);
1328 /* pg_ident.conf */
1330 conflines = readfile(ident_file);
1332 snprintf(path, sizeof(path), "%s/pg_ident.conf", pg_data);
1334 writefile(path, conflines);
1335 if (chmod(path, pg_file_create_mode) != 0)
1337 pg_log_error("could not change permissions of \"%s\": %m", path);
1338 exit(1);
1341 free(conflines);
1343 check_ok();
1348 * run the BKI script in bootstrap mode to create template1
1350 static void
1351 bootstrap_template1(void)
1353 PG_CMD_DECL;
1354 char **line;
1355 char **bki_lines;
1356 char headerline[MAXPGPATH];
1357 char buf[64];
1359 printf(_("running bootstrap script ... "));
1360 fflush(stdout);
1362 bki_lines = readfile(bki_file);
1364 /* Check that bki file appears to be of the right version */
1366 snprintf(headerline, sizeof(headerline), "# PostgreSQL %s\n",
1367 PG_MAJORVERSION);
1369 if (strcmp(headerline, *bki_lines) != 0)
1371 pg_log_error("input file \"%s\" does not belong to PostgreSQL %s",
1372 bki_file, PG_VERSION);
1373 fprintf(stderr,
1374 _("Check your installation or specify the correct path "
1375 "using the option -L.\n"));
1376 exit(1);
1379 /* Substitute for various symbols used in the BKI file */
1381 sprintf(buf, "%d", NAMEDATALEN);
1382 bki_lines = replace_token(bki_lines, "NAMEDATALEN", buf);
1384 sprintf(buf, "%d", (int) sizeof(Pointer));
1385 bki_lines = replace_token(bki_lines, "SIZEOF_POINTER", buf);
1387 bki_lines = replace_token(bki_lines, "ALIGNOF_POINTER",
1388 (sizeof(Pointer) == 4) ? "i" : "d");
1390 bki_lines = replace_token(bki_lines, "FLOAT8PASSBYVAL",
1391 FLOAT8PASSBYVAL ? "true" : "false");
1393 bki_lines = replace_token(bki_lines, "POSTGRES",
1394 escape_quotes_bki(username));
1396 bki_lines = replace_token(bki_lines, "ENCODING",
1397 encodingid_to_string(encodingid));
1399 bki_lines = replace_token(bki_lines, "LC_COLLATE",
1400 escape_quotes_bki(lc_collate));
1402 bki_lines = replace_token(bki_lines, "LC_CTYPE",
1403 escape_quotes_bki(lc_ctype));
1405 /* Also ensure backend isn't confused by this environment var: */
1406 unsetenv("PGCLIENTENCODING");
1408 snprintf(cmd, sizeof(cmd),
1409 "\"%s\" --boot -X %u %s %s %s %s",
1410 backend_exec,
1411 wal_segment_size_mb * (1024 * 1024),
1412 data_checksums ? "-k" : "",
1413 boot_options, extra_options,
1414 debug ? "-d 5" : "");
1417 PG_CMD_OPEN;
1419 for (line = bki_lines; *line != NULL; line++)
1421 PG_CMD_PUTS(*line);
1422 free(*line);
1425 PG_CMD_CLOSE;
1427 free(bki_lines);
1429 check_ok();
1433 * set up the shadow password table
1435 static void
1436 setup_auth(FILE *cmdfd)
1438 const char *const *line;
1439 static const char *const pg_authid_setup[] = {
1441 * The authid table shouldn't be readable except through views, to
1442 * ensure passwords are not publicly visible.
1444 "REVOKE ALL ON pg_authid FROM public;\n\n",
1445 NULL
1448 for (line = pg_authid_setup; *line != NULL; line++)
1449 PG_CMD_PUTS(*line);
1451 if (superuser_password)
1452 PG_CMD_PRINTF("ALTER USER \"%s\" WITH PASSWORD E'%s';\n\n",
1453 username, escape_quotes(superuser_password));
1457 * get the superuser password if required
1459 static void
1460 get_su_pwd(void)
1462 char *pwd1;
1464 if (pwprompt)
1467 * Read password from terminal
1469 char *pwd2;
1471 printf("\n");
1472 fflush(stdout);
1473 pwd1 = simple_prompt("Enter new superuser password: ", false);
1474 pwd2 = simple_prompt("Enter it again: ", false);
1475 if (strcmp(pwd1, pwd2) != 0)
1477 fprintf(stderr, _("Passwords didn't match.\n"));
1478 exit(1);
1480 free(pwd2);
1482 else
1485 * Read password from file
1487 * Ideally this should insist that the file not be world-readable.
1488 * However, this option is mainly intended for use on Windows where
1489 * file permissions may not exist at all, so we'll skip the paranoia
1490 * for now.
1492 FILE *pwf = fopen(pwfilename, "r");
1494 if (!pwf)
1496 pg_log_error("could not open file \"%s\" for reading: %m",
1497 pwfilename);
1498 exit(1);
1500 pwd1 = pg_get_line(pwf);
1501 if (!pwd1)
1503 if (ferror(pwf))
1504 pg_log_error("could not read password from file \"%s\": %m",
1505 pwfilename);
1506 else
1507 pg_log_error("password file \"%s\" is empty",
1508 pwfilename);
1509 exit(1);
1511 fclose(pwf);
1513 (void) pg_strip_crlf(pwd1);
1516 superuser_password = pwd1;
1520 * set up pg_depend
1522 static void
1523 setup_depend(FILE *cmdfd)
1525 const char *const *line;
1526 static const char *const pg_depend_setup[] = {
1528 * Advance the OID counter so that subsequently-created objects aren't
1529 * pinned.
1531 "SELECT pg_stop_making_pinned_objects();\n\n",
1532 NULL
1535 for (line = pg_depend_setup; *line != NULL; line++)
1536 PG_CMD_PUTS(*line);
1540 * Run external file
1542 static void
1543 setup_run_file(FILE *cmdfd, const char *filename)
1545 char **lines;
1547 lines = readfile(filename);
1549 for (char **line = lines; *line != NULL; line++)
1551 PG_CMD_PUTS(*line);
1552 free(*line);
1555 PG_CMD_PUTS("\n\n");
1557 free(lines);
1561 * fill in extra description data
1563 static void
1564 setup_description(FILE *cmdfd)
1566 /* Create default descriptions for operator implementation functions */
1567 PG_CMD_PUTS("WITH funcdescs AS ( "
1568 "SELECT p.oid as p_oid, o.oid as o_oid, oprname "
1569 "FROM pg_proc p JOIN pg_operator o ON oprcode = p.oid ) "
1570 "INSERT INTO pg_description "
1571 " SELECT p_oid, 'pg_proc'::regclass, 0, "
1572 " 'implementation of ' || oprname || ' operator' "
1573 " FROM funcdescs "
1574 " WHERE NOT EXISTS (SELECT 1 FROM pg_description "
1575 " WHERE objoid = p_oid AND classoid = 'pg_proc'::regclass) "
1576 " AND NOT EXISTS (SELECT 1 FROM pg_description "
1577 " WHERE objoid = o_oid AND classoid = 'pg_operator'::regclass"
1578 " AND description LIKE 'deprecated%');\n\n");
1582 * populate pg_collation
1584 static void
1585 setup_collation(FILE *cmdfd)
1588 * Add an SQL-standard name. We don't want to pin this, so it doesn't go
1589 * in pg_collation.h. But add it before reading system collations, so
1590 * that it wins if libc defines a locale named ucs_basic.
1592 PG_CMD_PRINTF("INSERT INTO pg_collation (oid, collname, collnamespace, collowner, collprovider, collisdeterministic, collencoding, collcollate, collctype)"
1593 "VALUES (pg_nextoid('pg_catalog.pg_collation', 'oid', 'pg_catalog.pg_collation_oid_index'), 'ucs_basic', 'pg_catalog'::regnamespace, %u, '%c', true, %d, 'C', 'C');\n\n",
1594 BOOTSTRAP_SUPERUSERID, COLLPROVIDER_LIBC, PG_UTF8);
1596 /* Now import all collations we can find in the operating system */
1597 PG_CMD_PUTS("SELECT pg_import_system_collations('pg_catalog');\n\n");
1601 * Set up privileges
1603 * We mark most system catalogs as world-readable. We don't currently have
1604 * to touch functions, languages, or databases, because their default
1605 * permissions are OK.
1607 * Some objects may require different permissions by default, so we
1608 * make sure we don't overwrite privilege sets that have already been
1609 * set (NOT NULL).
1611 * Also populate pg_init_privs to save what the privileges are at init
1612 * time. This is used by pg_dump to allow users to change privileges
1613 * on catalog objects and to have those privilege changes preserved
1614 * across dump/reload and pg_upgrade.
1616 * Note that pg_init_privs is only for per-database objects and therefore
1617 * we don't include databases or tablespaces.
1619 static void
1620 setup_privileges(FILE *cmdfd)
1622 char **line;
1623 char **priv_lines;
1624 static char *privileges_setup[] = {
1625 "UPDATE pg_class "
1626 " SET relacl = (SELECT array_agg(a.acl) FROM "
1627 " (SELECT E'=r/\"$POSTGRES_SUPERUSERNAME\"' as acl "
1628 " UNION SELECT unnest(pg_catalog.acldefault("
1629 " CASE WHEN relkind = " CppAsString2(RELKIND_SEQUENCE) " THEN 's' "
1630 " ELSE 'r' END::\"char\"," CppAsString2(BOOTSTRAP_SUPERUSERID) "::oid))"
1631 " ) as a) "
1632 " WHERE relkind IN (" CppAsString2(RELKIND_RELATION) ", "
1633 CppAsString2(RELKIND_VIEW) ", " CppAsString2(RELKIND_MATVIEW) ", "
1634 CppAsString2(RELKIND_SEQUENCE) ")"
1635 " AND relacl IS NULL;\n\n",
1636 "GRANT USAGE ON SCHEMA pg_catalog TO PUBLIC;\n\n",
1637 "GRANT CREATE, USAGE ON SCHEMA public TO PUBLIC;\n\n",
1638 "REVOKE ALL ON pg_largeobject FROM PUBLIC;\n\n",
1639 "INSERT INTO pg_init_privs "
1640 " (objoid, classoid, objsubid, initprivs, privtype)"
1641 " SELECT"
1642 " oid,"
1643 " (SELECT oid FROM pg_class WHERE relname = 'pg_class'),"
1644 " 0,"
1645 " relacl,"
1646 " 'i'"
1647 " FROM"
1648 " pg_class"
1649 " WHERE"
1650 " relacl IS NOT NULL"
1651 " AND relkind IN (" CppAsString2(RELKIND_RELATION) ", "
1652 CppAsString2(RELKIND_VIEW) ", " CppAsString2(RELKIND_MATVIEW) ", "
1653 CppAsString2(RELKIND_SEQUENCE) ");\n\n",
1654 "INSERT INTO pg_init_privs "
1655 " (objoid, classoid, objsubid, initprivs, privtype)"
1656 " SELECT"
1657 " pg_class.oid,"
1658 " (SELECT oid FROM pg_class WHERE relname = 'pg_class'),"
1659 " pg_attribute.attnum,"
1660 " pg_attribute.attacl,"
1661 " 'i'"
1662 " FROM"
1663 " pg_class"
1664 " JOIN pg_attribute ON (pg_class.oid = pg_attribute.attrelid)"
1665 " WHERE"
1666 " pg_attribute.attacl IS NOT NULL"
1667 " AND pg_class.relkind IN (" CppAsString2(RELKIND_RELATION) ", "
1668 CppAsString2(RELKIND_VIEW) ", " CppAsString2(RELKIND_MATVIEW) ", "
1669 CppAsString2(RELKIND_SEQUENCE) ");\n\n",
1670 "INSERT INTO pg_init_privs "
1671 " (objoid, classoid, objsubid, initprivs, privtype)"
1672 " SELECT"
1673 " oid,"
1674 " (SELECT oid FROM pg_class WHERE relname = 'pg_proc'),"
1675 " 0,"
1676 " proacl,"
1677 " 'i'"
1678 " FROM"
1679 " pg_proc"
1680 " WHERE"
1681 " proacl IS NOT NULL;\n\n",
1682 "INSERT INTO pg_init_privs "
1683 " (objoid, classoid, objsubid, initprivs, privtype)"
1684 " SELECT"
1685 " oid,"
1686 " (SELECT oid FROM pg_class WHERE relname = 'pg_type'),"
1687 " 0,"
1688 " typacl,"
1689 " 'i'"
1690 " FROM"
1691 " pg_type"
1692 " WHERE"
1693 " typacl IS NOT NULL;\n\n",
1694 "INSERT INTO pg_init_privs "
1695 " (objoid, classoid, objsubid, initprivs, privtype)"
1696 " SELECT"
1697 " oid,"
1698 " (SELECT oid FROM pg_class WHERE relname = 'pg_language'),"
1699 " 0,"
1700 " lanacl,"
1701 " 'i'"
1702 " FROM"
1703 " pg_language"
1704 " WHERE"
1705 " lanacl IS NOT NULL;\n\n",
1706 "INSERT INTO pg_init_privs "
1707 " (objoid, classoid, objsubid, initprivs, privtype)"
1708 " SELECT"
1709 " oid,"
1710 " (SELECT oid FROM pg_class WHERE "
1711 " relname = 'pg_largeobject_metadata'),"
1712 " 0,"
1713 " lomacl,"
1714 " 'i'"
1715 " FROM"
1716 " pg_largeobject_metadata"
1717 " WHERE"
1718 " lomacl IS NOT NULL;\n\n",
1719 "INSERT INTO pg_init_privs "
1720 " (objoid, classoid, objsubid, initprivs, privtype)"
1721 " SELECT"
1722 " oid,"
1723 " (SELECT oid FROM pg_class WHERE relname = 'pg_namespace'),"
1724 " 0,"
1725 " nspacl,"
1726 " 'i'"
1727 " FROM"
1728 " pg_namespace"
1729 " WHERE"
1730 " nspacl IS NOT NULL;\n\n",
1731 "INSERT INTO pg_init_privs "
1732 " (objoid, classoid, objsubid, initprivs, privtype)"
1733 " SELECT"
1734 " oid,"
1735 " (SELECT oid FROM pg_class WHERE "
1736 " relname = 'pg_foreign_data_wrapper'),"
1737 " 0,"
1738 " fdwacl,"
1739 " 'i'"
1740 " FROM"
1741 " pg_foreign_data_wrapper"
1742 " WHERE"
1743 " fdwacl IS NOT NULL;\n\n",
1744 "INSERT INTO pg_init_privs "
1745 " (objoid, classoid, objsubid, initprivs, privtype)"
1746 " SELECT"
1747 " oid,"
1748 " (SELECT oid FROM pg_class "
1749 " WHERE relname = 'pg_foreign_server'),"
1750 " 0,"
1751 " srvacl,"
1752 " 'i'"
1753 " FROM"
1754 " pg_foreign_server"
1755 " WHERE"
1756 " srvacl IS NOT NULL;\n\n",
1757 NULL
1760 priv_lines = replace_token(privileges_setup, "$POSTGRES_SUPERUSERNAME",
1761 escape_quotes(username));
1762 for (line = priv_lines; *line != NULL; line++)
1763 PG_CMD_PUTS(*line);
1767 * extract the strange version of version required for information schema
1768 * (09.08.0007abc)
1770 static void
1771 set_info_version(void)
1773 char *letterversion;
1774 long major = 0,
1775 minor = 0,
1776 micro = 0;
1777 char *endptr;
1778 char *vstr = pg_strdup(PG_VERSION);
1779 char *ptr;
1781 ptr = vstr + (strlen(vstr) - 1);
1782 while (ptr != vstr && (*ptr < '0' || *ptr > '9'))
1783 ptr--;
1784 letterversion = ptr + 1;
1785 major = strtol(vstr, &endptr, 10);
1786 if (*endptr)
1787 minor = strtol(endptr + 1, &endptr, 10);
1788 if (*endptr)
1789 micro = strtol(endptr + 1, &endptr, 10);
1790 snprintf(infoversion, sizeof(infoversion), "%02ld.%02ld.%04ld%s",
1791 major, minor, micro, letterversion);
1795 * load info schema and populate from features file
1797 static void
1798 setup_schema(FILE *cmdfd)
1800 setup_run_file(cmdfd, info_schema_file);
1802 PG_CMD_PRINTF("UPDATE information_schema.sql_implementation_info "
1803 " SET character_value = '%s' "
1804 " WHERE implementation_info_name = 'DBMS VERSION';\n\n",
1805 infoversion);
1807 PG_CMD_PRINTF("COPY information_schema.sql_features "
1808 " (feature_id, feature_name, sub_feature_id, "
1809 " sub_feature_name, is_supported, comments) "
1810 " FROM E'%s';\n\n",
1811 escape_quotes(features_file));
1815 * load PL/pgSQL server-side language
1817 static void
1818 load_plpgsql(FILE *cmdfd)
1820 PG_CMD_PUTS("CREATE EXTENSION plpgsql;\n\n");
1824 * clean everything up in template1
1826 static void
1827 vacuum_db(FILE *cmdfd)
1829 /* Run analyze before VACUUM so the statistics are frozen. */
1830 PG_CMD_PUTS("ANALYZE;\n\nVACUUM FREEZE;\n\n");
1834 * copy template1 to template0
1836 static void
1837 make_template0(FILE *cmdfd)
1839 const char *const *line;
1840 static const char *const template0_setup[] = {
1841 "CREATE DATABASE template0 IS_TEMPLATE = true ALLOW_CONNECTIONS = false;\n\n",
1844 * We use the OID of template0 to determine datlastsysoid
1846 "UPDATE pg_database SET datlastsysoid = "
1847 " (SELECT oid FROM pg_database "
1848 " WHERE datname = 'template0');\n\n",
1851 * Explicitly revoke public create-schema and create-temp-table
1852 * privileges in template1 and template0; else the latter would be on
1853 * by default
1855 "REVOKE CREATE,TEMPORARY ON DATABASE template1 FROM public;\n\n",
1856 "REVOKE CREATE,TEMPORARY ON DATABASE template0 FROM public;\n\n",
1858 "COMMENT ON DATABASE template0 IS 'unmodifiable empty database';\n\n",
1861 * Finally vacuum to clean up dead rows in pg_database
1863 "VACUUM pg_database;\n\n",
1864 NULL
1867 for (line = template0_setup; *line; line++)
1868 PG_CMD_PUTS(*line);
1872 * copy template1 to postgres
1874 static void
1875 make_postgres(FILE *cmdfd)
1877 const char *const *line;
1878 static const char *const postgres_setup[] = {
1879 "CREATE DATABASE postgres;\n\n",
1880 "COMMENT ON DATABASE postgres IS 'default administrative connection database';\n\n",
1881 NULL
1884 for (line = postgres_setup; *line; line++)
1885 PG_CMD_PUTS(*line);
1889 * signal handler in case we are interrupted.
1891 * The Windows runtime docs at
1892 * https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/signal
1893 * specifically forbid a number of things being done from a signal handler,
1894 * including IO, memory allocation and system calls, and only allow jmpbuf
1895 * if you are handling SIGFPE.
1897 * I avoided doing the forbidden things by setting a flag instead of calling
1898 * exit() directly.
1900 * Also note the behaviour of Windows with SIGINT, which says this:
1901 * SIGINT is not supported for any Win32 application. When a CTRL+C interrupt
1902 * occurs, Win32 operating systems generate a new thread to specifically
1903 * handle that interrupt. This can cause a single-thread application, such as
1904 * one in UNIX, to become multithreaded and cause unexpected behavior.
1906 * I have no idea how to handle this. (Strange they call UNIX an application!)
1907 * So this will need some testing on Windows.
1909 static void
1910 trapsig(int signum)
1912 /* handle systems that reset the handler, like Windows (grr) */
1913 pqsignal(signum, trapsig);
1914 caught_signal = true;
1918 * call exit() if we got a signal, or else output "ok".
1920 static void
1921 check_ok(void)
1923 if (caught_signal)
1925 printf(_("caught signal\n"));
1926 fflush(stdout);
1927 exit(1);
1929 else if (output_failed)
1931 printf(_("could not write to child process: %s\n"),
1932 strerror(output_errno));
1933 fflush(stdout);
1934 exit(1);
1936 else
1938 /* all seems well */
1939 printf(_("ok\n"));
1940 fflush(stdout);
1944 /* Hack to suppress a warning about %x from some versions of gcc */
1945 static inline size_t
1946 my_strftime(char *s, size_t max, const char *fmt, const struct tm *tm)
1948 return strftime(s, max, fmt, tm);
1952 * Determine likely date order from locale
1954 static int
1955 locale_date_order(const char *locale)
1957 struct tm testtime;
1958 char buf[128];
1959 char *posD;
1960 char *posM;
1961 char *posY;
1962 char *save;
1963 size_t res;
1964 int result;
1966 result = DATEORDER_MDY; /* default */
1968 save = setlocale(LC_TIME, NULL);
1969 if (!save)
1970 return result;
1971 save = pg_strdup(save);
1973 setlocale(LC_TIME, locale);
1975 memset(&testtime, 0, sizeof(testtime));
1976 testtime.tm_mday = 22;
1977 testtime.tm_mon = 10; /* November, should come out as "11" */
1978 testtime.tm_year = 133; /* 2033 */
1980 res = my_strftime(buf, sizeof(buf), "%x", &testtime);
1982 setlocale(LC_TIME, save);
1983 free(save);
1985 if (res == 0)
1986 return result;
1988 posM = strstr(buf, "11");
1989 posD = strstr(buf, "22");
1990 posY = strstr(buf, "33");
1992 if (!posM || !posD || !posY)
1993 return result;
1995 if (posY < posM && posM < posD)
1996 result = DATEORDER_YMD;
1997 else if (posD < posM)
1998 result = DATEORDER_DMY;
1999 else
2000 result = DATEORDER_MDY;
2002 return result;
2006 * Verify that locale name is valid for the locale category.
2008 * If successful, and canonname isn't NULL, a malloc'd copy of the locale's
2009 * canonical name is stored there. This is especially useful for figuring out
2010 * what locale name "" means (ie, the environment value). (Actually,
2011 * it seems that on most implementations that's the only thing it's good for;
2012 * we could wish that setlocale gave back a canonically spelled version of
2013 * the locale name, but typically it doesn't.)
2015 * this should match the backend's check_locale() function
2017 static void
2018 check_locale_name(int category, const char *locale, char **canonname)
2020 char *save;
2021 char *res;
2023 if (canonname)
2024 *canonname = NULL; /* in case of failure */
2026 save = setlocale(category, NULL);
2027 if (!save)
2029 pg_log_error("setlocale() failed");
2030 exit(1);
2033 /* save may be pointing at a modifiable scratch variable, so copy it. */
2034 save = pg_strdup(save);
2036 /* for setlocale() call */
2037 if (!locale)
2038 locale = "";
2040 /* set the locale with setlocale, to see if it accepts it. */
2041 res = setlocale(category, locale);
2043 /* save canonical name if requested. */
2044 if (res && canonname)
2045 *canonname = pg_strdup(res);
2047 /* restore old value. */
2048 if (!setlocale(category, save))
2050 pg_log_error("failed to restore old locale \"%s\"", save);
2051 exit(1);
2053 free(save);
2055 /* complain if locale wasn't valid */
2056 if (res == NULL)
2058 if (*locale)
2059 pg_log_error("invalid locale name \"%s\"", locale);
2060 else
2063 * If no relevant switch was given on command line, locale is an
2064 * empty string, which is not too helpful to report. Presumably
2065 * setlocale() found something it did not like in the environment.
2066 * Ideally we'd report the bad environment variable, but since
2067 * setlocale's behavior is implementation-specific, it's hard to
2068 * be sure what it didn't like. Print a safe generic message.
2070 pg_log_error("invalid locale settings; check LANG and LC_* environment variables");
2072 exit(1);
2077 * check if the chosen encoding matches the encoding required by the locale
2079 * this should match the similar check in the backend createdb() function
2081 static bool
2082 check_locale_encoding(const char *locale, int user_enc)
2084 int locale_enc;
2086 locale_enc = pg_get_encoding_from_locale(locale, true);
2088 /* See notes in createdb() to understand these tests */
2089 if (!(locale_enc == user_enc ||
2090 locale_enc == PG_SQL_ASCII ||
2091 locale_enc == -1 ||
2092 #ifdef WIN32
2093 user_enc == PG_UTF8 ||
2094 #endif
2095 user_enc == PG_SQL_ASCII))
2097 pg_log_error("encoding mismatch");
2098 fprintf(stderr,
2099 _("The encoding you selected (%s) and the encoding that the\n"
2100 "selected locale uses (%s) do not match. This would lead to\n"
2101 "misbehavior in various character string processing functions.\n"
2102 "Rerun %s and either do not specify an encoding explicitly,\n"
2103 "or choose a matching combination.\n"),
2104 pg_encoding_to_char(user_enc),
2105 pg_encoding_to_char(locale_enc),
2106 progname);
2107 return false;
2109 return true;
2113 * set up the locale variables
2115 * assumes we have called setlocale(LC_ALL, "") -- see set_pglocale_pgservice
2117 static void
2118 setlocales(void)
2120 char *canonname;
2122 /* set empty lc_* values to locale config if set */
2124 if (locale)
2126 if (!lc_ctype)
2127 lc_ctype = locale;
2128 if (!lc_collate)
2129 lc_collate = locale;
2130 if (!lc_numeric)
2131 lc_numeric = locale;
2132 if (!lc_time)
2133 lc_time = locale;
2134 if (!lc_monetary)
2135 lc_monetary = locale;
2136 if (!lc_messages)
2137 lc_messages = locale;
2141 * canonicalize locale names, and obtain any missing values from our
2142 * current environment
2145 check_locale_name(LC_CTYPE, lc_ctype, &canonname);
2146 lc_ctype = canonname;
2147 check_locale_name(LC_COLLATE, lc_collate, &canonname);
2148 lc_collate = canonname;
2149 check_locale_name(LC_NUMERIC, lc_numeric, &canonname);
2150 lc_numeric = canonname;
2151 check_locale_name(LC_TIME, lc_time, &canonname);
2152 lc_time = canonname;
2153 check_locale_name(LC_MONETARY, lc_monetary, &canonname);
2154 lc_monetary = canonname;
2155 #if defined(LC_MESSAGES) && !defined(WIN32)
2156 check_locale_name(LC_MESSAGES, lc_messages, &canonname);
2157 lc_messages = canonname;
2158 #else
2159 /* when LC_MESSAGES is not available, use the LC_CTYPE setting */
2160 check_locale_name(LC_CTYPE, lc_messages, &canonname);
2161 lc_messages = canonname;
2162 #endif
2166 * print help text
2168 static void
2169 usage(const char *progname)
2171 printf(_("%s initializes a PostgreSQL database cluster.\n\n"), progname);
2172 printf(_("Usage:\n"));
2173 printf(_(" %s [OPTION]... [DATADIR]\n"), progname);
2174 printf(_("\nOptions:\n"));
2175 printf(_(" -A, --auth=METHOD default authentication method for local connections\n"));
2176 printf(_(" --auth-host=METHOD default authentication method for local TCP/IP connections\n"));
2177 printf(_(" --auth-local=METHOD default authentication method for local-socket connections\n"));
2178 printf(_(" [-D, --pgdata=]DATADIR location for this database cluster\n"));
2179 printf(_(" -E, --encoding=ENCODING set default encoding for new databases\n"));
2180 printf(_(" -g, --allow-group-access allow group read/execute on data directory\n"));
2181 printf(_(" -k, --data-checksums use data page checksums\n"));
2182 printf(_(" --locale=LOCALE set default locale for new databases\n"));
2183 printf(_(" --lc-collate=, --lc-ctype=, --lc-messages=LOCALE\n"
2184 " --lc-monetary=, --lc-numeric=, --lc-time=LOCALE\n"
2185 " set default locale in the respective category for\n"
2186 " new databases (default taken from environment)\n"));
2187 printf(_(" --no-locale equivalent to --locale=C\n"));
2188 printf(_(" --pwfile=FILE read password for the new superuser from file\n"));
2189 printf(_(" -T, --text-search-config=CFG\n"
2190 " default text search configuration\n"));
2191 printf(_(" -U, --username=NAME database superuser name\n"));
2192 printf(_(" -W, --pwprompt prompt for a password for the new superuser\n"));
2193 printf(_(" -X, --waldir=WALDIR location for the write-ahead log directory\n"));
2194 printf(_(" --wal-segsize=SIZE size of WAL segments, in megabytes\n"));
2195 printf(_("\nLess commonly used options:\n"));
2196 printf(_(" -d, --debug generate lots of debugging output\n"));
2197 printf(_(" --discard-caches set debug_discard_caches=1\n"));
2198 printf(_(" -L DIRECTORY where to find the input files\n"));
2199 printf(_(" -n, --no-clean do not clean up after errors\n"));
2200 printf(_(" -N, --no-sync do not wait for changes to be written safely to disk\n"));
2201 printf(_(" --no-instructions do not print instructions for next steps\n"));
2202 printf(_(" -s, --show show internal settings\n"));
2203 printf(_(" -S, --sync-only only sync database files to disk, then exit\n"));
2204 printf(_("\nOther options:\n"));
2205 printf(_(" -V, --version output version information, then exit\n"));
2206 printf(_(" -?, --help show this help, then exit\n"));
2207 printf(_("\nIf the data directory is not specified, the environment variable PGDATA\n"
2208 "is used.\n"));
2209 printf(_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
2210 printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
2213 static void
2214 check_authmethod_unspecified(const char **authmethod)
2216 if (*authmethod == NULL)
2218 authwarning = true;
2219 *authmethod = "trust";
2223 static void
2224 check_authmethod_valid(const char *authmethod, const char *const *valid_methods, const char *conntype)
2226 const char *const *p;
2228 for (p = valid_methods; *p; p++)
2230 if (strcmp(authmethod, *p) == 0)
2231 return;
2232 /* with space = param */
2233 if (strchr(authmethod, ' '))
2234 if (strncmp(authmethod, *p, (authmethod - strchr(authmethod, ' '))) == 0)
2235 return;
2238 pg_log_error("invalid authentication method \"%s\" for \"%s\" connections",
2239 authmethod, conntype);
2240 exit(1);
2243 static void
2244 check_need_password(const char *authmethodlocal, const char *authmethodhost)
2246 if ((strcmp(authmethodlocal, "md5") == 0 ||
2247 strcmp(authmethodlocal, "password") == 0 ||
2248 strcmp(authmethodlocal, "scram-sha-256") == 0) &&
2249 (strcmp(authmethodhost, "md5") == 0 ||
2250 strcmp(authmethodhost, "password") == 0 ||
2251 strcmp(authmethodhost, "scram-sha-256") == 0) &&
2252 !(pwprompt || pwfilename))
2254 pg_log_error("must specify a password for the superuser to enable password authentication");
2255 exit(1);
2260 void
2261 setup_pgdata(void)
2263 char *pgdata_get_env;
2265 if (!pg_data)
2267 pgdata_get_env = getenv("PGDATA");
2268 if (pgdata_get_env && strlen(pgdata_get_env))
2270 /* PGDATA found */
2271 pg_data = pg_strdup(pgdata_get_env);
2273 else
2275 pg_log_error("no data directory specified");
2276 fprintf(stderr,
2277 _("You must identify the directory where the data for this database system\n"
2278 "will reside. Do this with either the invocation option -D or the\n"
2279 "environment variable PGDATA.\n"));
2280 exit(1);
2284 pgdata_native = pg_strdup(pg_data);
2285 canonicalize_path(pg_data);
2288 * we have to set PGDATA for postgres rather than pass it on the command
2289 * line to avoid dumb quoting problems on Windows, and we would especially
2290 * need quotes otherwise on Windows because paths there are most likely to
2291 * have embedded spaces.
2293 if (setenv("PGDATA", pg_data, 1) != 0)
2295 pg_log_error("could not set environment");
2296 exit(1);
2301 void
2302 setup_bin_paths(const char *argv0)
2304 int ret;
2306 if ((ret = find_other_exec(argv0, "postgres", PG_BACKEND_VERSIONSTR,
2307 backend_exec)) < 0)
2309 char full_path[MAXPGPATH];
2311 if (find_my_exec(argv0, full_path) < 0)
2312 strlcpy(full_path, progname, sizeof(full_path));
2314 if (ret == -1)
2315 pg_log_error("The program \"%s\" is needed by %s but was not found in the\n"
2316 "same directory as \"%s\".\n"
2317 "Check your installation.",
2318 "postgres", progname, full_path);
2319 else
2320 pg_log_error("The program \"%s\" was found by \"%s\"\n"
2321 "but was not the same version as %s.\n"
2322 "Check your installation.",
2323 "postgres", full_path, progname);
2324 exit(1);
2327 /* store binary directory */
2328 strcpy(bin_path, backend_exec);
2329 *last_dir_separator(bin_path) = '\0';
2330 canonicalize_path(bin_path);
2332 if (!share_path)
2334 share_path = pg_malloc(MAXPGPATH);
2335 get_share_path(backend_exec, share_path);
2337 else if (!is_absolute_path(share_path))
2339 pg_log_error("input file location must be an absolute path");
2340 exit(1);
2343 canonicalize_path(share_path);
2346 void
2347 setup_locale_encoding(void)
2349 setlocales();
2351 if (strcmp(lc_ctype, lc_collate) == 0 &&
2352 strcmp(lc_ctype, lc_time) == 0 &&
2353 strcmp(lc_ctype, lc_numeric) == 0 &&
2354 strcmp(lc_ctype, lc_monetary) == 0 &&
2355 strcmp(lc_ctype, lc_messages) == 0)
2356 printf(_("The database cluster will be initialized with locale \"%s\".\n"), lc_ctype);
2357 else
2359 printf(_("The database cluster will be initialized with locales\n"
2360 " COLLATE: %s\n"
2361 " CTYPE: %s\n"
2362 " MESSAGES: %s\n"
2363 " MONETARY: %s\n"
2364 " NUMERIC: %s\n"
2365 " TIME: %s\n"),
2366 lc_collate,
2367 lc_ctype,
2368 lc_messages,
2369 lc_monetary,
2370 lc_numeric,
2371 lc_time);
2374 if (!encoding)
2376 int ctype_enc;
2378 ctype_enc = pg_get_encoding_from_locale(lc_ctype, true);
2380 if (ctype_enc == -1)
2382 /* Couldn't recognize the locale's codeset */
2383 pg_log_error("could not find suitable encoding for locale \"%s\"",
2384 lc_ctype);
2385 fprintf(stderr, _("Rerun %s with the -E option.\n"), progname);
2386 fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2387 progname);
2388 exit(1);
2390 else if (!pg_valid_server_encoding_id(ctype_enc))
2393 * We recognized it, but it's not a legal server encoding. On
2394 * Windows, UTF-8 works with any locale, so we can fall back to
2395 * UTF-8.
2397 #ifdef WIN32
2398 encodingid = PG_UTF8;
2399 printf(_("Encoding \"%s\" implied by locale is not allowed as a server-side encoding.\n"
2400 "The default database encoding will be set to \"%s\" instead.\n"),
2401 pg_encoding_to_char(ctype_enc),
2402 pg_encoding_to_char(encodingid));
2403 #else
2404 pg_log_error("locale \"%s\" requires unsupported encoding \"%s\"",
2405 lc_ctype, pg_encoding_to_char(ctype_enc));
2406 fprintf(stderr,
2407 _("Encoding \"%s\" is not allowed as a server-side encoding.\n"
2408 "Rerun %s with a different locale selection.\n"),
2409 pg_encoding_to_char(ctype_enc), progname);
2410 exit(1);
2411 #endif
2413 else
2415 encodingid = ctype_enc;
2416 printf(_("The default database encoding has accordingly been set to \"%s\".\n"),
2417 pg_encoding_to_char(encodingid));
2420 else
2421 encodingid = get_encoding_id(encoding);
2423 if (!check_locale_encoding(lc_ctype, encodingid) ||
2424 !check_locale_encoding(lc_collate, encodingid))
2425 exit(1); /* check_locale_encoding printed the error */
2430 void
2431 setup_data_file_paths(void)
2433 set_input(&bki_file, "postgres.bki");
2434 set_input(&hba_file, "pg_hba.conf.sample");
2435 set_input(&ident_file, "pg_ident.conf.sample");
2436 set_input(&conf_file, "postgresql.conf.sample");
2437 set_input(&dictionary_file, "snowball_create.sql");
2438 set_input(&info_schema_file, "information_schema.sql");
2439 set_input(&features_file, "sql_features.txt");
2440 set_input(&system_constraints_file, "system_constraints.sql");
2441 set_input(&system_functions_file, "system_functions.sql");
2442 set_input(&system_views_file, "system_views.sql");
2444 if (show_setting || debug)
2446 fprintf(stderr,
2447 "VERSION=%s\n"
2448 "PGDATA=%s\nshare_path=%s\nPGPATH=%s\n"
2449 "POSTGRES_SUPERUSERNAME=%s\nPOSTGRES_BKI=%s\n"
2450 "POSTGRESQL_CONF_SAMPLE=%s\n"
2451 "PG_HBA_SAMPLE=%s\nPG_IDENT_SAMPLE=%s\n",
2452 PG_VERSION,
2453 pg_data, share_path, bin_path,
2454 username, bki_file,
2455 conf_file,
2456 hba_file, ident_file);
2457 if (show_setting)
2458 exit(0);
2461 check_input(bki_file);
2462 check_input(hba_file);
2463 check_input(ident_file);
2464 check_input(conf_file);
2465 check_input(dictionary_file);
2466 check_input(info_schema_file);
2467 check_input(features_file);
2468 check_input(system_constraints_file);
2469 check_input(system_functions_file);
2470 check_input(system_views_file);
2474 void
2475 setup_text_search(void)
2477 if (!default_text_search_config)
2479 default_text_search_config = find_matching_ts_config(lc_ctype);
2480 if (!default_text_search_config)
2482 pg_log_info("could not find suitable text search configuration for locale \"%s\"",
2483 lc_ctype);
2484 default_text_search_config = "simple";
2487 else
2489 const char *checkmatch = find_matching_ts_config(lc_ctype);
2491 if (checkmatch == NULL)
2493 pg_log_warning("suitable text search configuration for locale \"%s\" is unknown",
2494 lc_ctype);
2496 else if (strcmp(checkmatch, default_text_search_config) != 0)
2498 pg_log_warning("specified text search configuration \"%s\" might not match locale \"%s\"",
2499 default_text_search_config, lc_ctype);
2503 printf(_("The default text search configuration will be set to \"%s\".\n"),
2504 default_text_search_config);
2509 void
2510 setup_signals(void)
2512 /* some of these are not valid on Windows */
2513 #ifdef SIGHUP
2514 pqsignal(SIGHUP, trapsig);
2515 #endif
2516 #ifdef SIGINT
2517 pqsignal(SIGINT, trapsig);
2518 #endif
2519 #ifdef SIGQUIT
2520 pqsignal(SIGQUIT, trapsig);
2521 #endif
2522 #ifdef SIGTERM
2523 pqsignal(SIGTERM, trapsig);
2524 #endif
2526 /* Ignore SIGPIPE when writing to backend, so we can clean up */
2527 #ifdef SIGPIPE
2528 pqsignal(SIGPIPE, SIG_IGN);
2529 #endif
2531 /* Prevent SIGSYS so we can probe for kernel calls that might not work */
2532 #ifdef SIGSYS
2533 pqsignal(SIGSYS, SIG_IGN);
2534 #endif
2538 void
2539 create_data_directory(void)
2541 int ret;
2543 switch ((ret = pg_check_dir(pg_data)))
2545 case 0:
2546 /* PGDATA not there, must create it */
2547 printf(_("creating directory %s ... "),
2548 pg_data);
2549 fflush(stdout);
2551 if (pg_mkdir_p(pg_data, pg_dir_create_mode) != 0)
2553 pg_log_error("could not create directory \"%s\": %m", pg_data);
2554 exit(1);
2556 else
2557 check_ok();
2559 made_new_pgdata = true;
2560 break;
2562 case 1:
2563 /* Present but empty, fix permissions and use it */
2564 printf(_("fixing permissions on existing directory %s ... "),
2565 pg_data);
2566 fflush(stdout);
2568 if (chmod(pg_data, pg_dir_create_mode) != 0)
2570 pg_log_error("could not change permissions of directory \"%s\": %m",
2571 pg_data);
2572 exit(1);
2574 else
2575 check_ok();
2577 found_existing_pgdata = true;
2578 break;
2580 case 2:
2581 case 3:
2582 case 4:
2583 /* Present and not empty */
2584 pg_log_error("directory \"%s\" exists but is not empty", pg_data);
2585 if (ret != 4)
2586 warn_on_mount_point(ret);
2587 else
2588 fprintf(stderr,
2589 _("If you want to create a new database system, either remove or empty\n"
2590 "the directory \"%s\" or run %s\n"
2591 "with an argument other than \"%s\".\n"),
2592 pg_data, progname, pg_data);
2593 exit(1); /* no further message needed */
2595 default:
2596 /* Trouble accessing directory */
2597 pg_log_error("could not access directory \"%s\": %m", pg_data);
2598 exit(1);
2603 /* Create WAL directory, and symlink if required */
2604 void
2605 create_xlog_or_symlink(void)
2607 char *subdirloc;
2609 /* form name of the place for the subdirectory or symlink */
2610 subdirloc = psprintf("%s/pg_wal", pg_data);
2612 if (xlog_dir)
2614 int ret;
2616 /* clean up xlog directory name, check it's absolute */
2617 canonicalize_path(xlog_dir);
2618 if (!is_absolute_path(xlog_dir))
2620 pg_log_error("WAL directory location must be an absolute path");
2621 exit(1);
2624 /* check if the specified xlog directory exists/is empty */
2625 switch ((ret = pg_check_dir(xlog_dir)))
2627 case 0:
2628 /* xlog directory not there, must create it */
2629 printf(_("creating directory %s ... "),
2630 xlog_dir);
2631 fflush(stdout);
2633 if (pg_mkdir_p(xlog_dir, pg_dir_create_mode) != 0)
2635 pg_log_error("could not create directory \"%s\": %m",
2636 xlog_dir);
2637 exit(1);
2639 else
2640 check_ok();
2642 made_new_xlogdir = true;
2643 break;
2645 case 1:
2646 /* Present but empty, fix permissions and use it */
2647 printf(_("fixing permissions on existing directory %s ... "),
2648 xlog_dir);
2649 fflush(stdout);
2651 if (chmod(xlog_dir, pg_dir_create_mode) != 0)
2653 pg_log_error("could not change permissions of directory \"%s\": %m",
2654 xlog_dir);
2655 exit(1);
2657 else
2658 check_ok();
2660 found_existing_xlogdir = true;
2661 break;
2663 case 2:
2664 case 3:
2665 case 4:
2666 /* Present and not empty */
2667 pg_log_error("directory \"%s\" exists but is not empty", xlog_dir);
2668 if (ret != 4)
2669 warn_on_mount_point(ret);
2670 else
2671 fprintf(stderr,
2672 _("If you want to store the WAL there, either remove or empty the directory\n"
2673 "\"%s\".\n"),
2674 xlog_dir);
2675 exit(1);
2677 default:
2678 /* Trouble accessing directory */
2679 pg_log_error("could not access directory \"%s\": %m", xlog_dir);
2680 exit(1);
2683 #ifdef HAVE_SYMLINK
2684 if (symlink(xlog_dir, subdirloc) != 0)
2686 pg_log_error("could not create symbolic link \"%s\": %m",
2687 subdirloc);
2688 exit(1);
2690 #else
2691 pg_log_error("symlinks are not supported on this platform");
2692 exit(1);
2693 #endif
2695 else
2697 /* Without -X option, just make the subdirectory normally */
2698 if (mkdir(subdirloc, pg_dir_create_mode) < 0)
2700 pg_log_error("could not create directory \"%s\": %m",
2701 subdirloc);
2702 exit(1);
2706 free(subdirloc);
2710 void
2711 warn_on_mount_point(int error)
2713 if (error == 2)
2714 fprintf(stderr,
2715 _("It contains a dot-prefixed/invisible file, perhaps due to it being a mount point.\n"));
2716 else if (error == 3)
2717 fprintf(stderr,
2718 _("It contains a lost+found directory, perhaps due to it being a mount point.\n"));
2720 fprintf(stderr,
2721 _("Using a mount point directly as the data directory is not recommended.\n"
2722 "Create a subdirectory under the mount point.\n"));
2726 void
2727 initialize_data_directory(void)
2729 PG_CMD_DECL;
2730 int i;
2732 setup_signals();
2735 * Set mask based on requested PGDATA permissions. pg_mode_mask, and
2736 * friends like pg_dir_create_mode, are set to owner-only by default and
2737 * then updated if -g is passed in by calling SetDataDirectoryCreatePerm()
2738 * when parsing our options (see above).
2740 umask(pg_mode_mask);
2742 create_data_directory();
2744 create_xlog_or_symlink();
2746 /* Create required subdirectories (other than pg_wal) */
2747 printf(_("creating subdirectories ... "));
2748 fflush(stdout);
2750 for (i = 0; i < lengthof(subdirs); i++)
2752 char *path;
2754 path = psprintf("%s/%s", pg_data, subdirs[i]);
2757 * The parent directory already exists, so we only need mkdir() not
2758 * pg_mkdir_p() here, which avoids some failure modes; cf bug #13853.
2760 if (mkdir(path, pg_dir_create_mode) < 0)
2762 pg_log_error("could not create directory \"%s\": %m", path);
2763 exit(1);
2766 free(path);
2769 check_ok();
2771 /* Top level PG_VERSION is checked by bootstrapper, so make it first */
2772 write_version_file(NULL);
2774 /* Select suitable configuration settings */
2775 set_null_conf();
2776 test_config_settings();
2778 /* Now create all the text config files */
2779 setup_config();
2781 /* Bootstrap template1 */
2782 bootstrap_template1();
2785 * Make the per-database PG_VERSION for template1 only after init'ing it
2787 write_version_file("base/1");
2790 * Create the stuff we don't need to use bootstrap mode for, using a
2791 * backend running in simple standalone mode.
2793 fputs(_("performing post-bootstrap initialization ... "), stdout);
2794 fflush(stdout);
2796 snprintf(cmd, sizeof(cmd),
2797 "\"%s\" %s %s template1 >%s",
2798 backend_exec, backend_options, extra_options,
2799 DEVNULL);
2801 PG_CMD_OPEN;
2803 setup_auth(cmdfd);
2805 setup_run_file(cmdfd, system_constraints_file);
2807 setup_run_file(cmdfd, system_functions_file);
2809 setup_depend(cmdfd);
2812 * Note that no objects created after setup_depend() will be "pinned".
2813 * They are all droppable at the whim of the DBA.
2816 setup_run_file(cmdfd, system_views_file);
2818 setup_description(cmdfd);
2820 setup_collation(cmdfd);
2822 setup_run_file(cmdfd, dictionary_file);
2824 setup_privileges(cmdfd);
2826 setup_schema(cmdfd);
2828 load_plpgsql(cmdfd);
2830 vacuum_db(cmdfd);
2832 make_template0(cmdfd);
2834 make_postgres(cmdfd);
2836 PG_CMD_CLOSE;
2838 check_ok();
2843 main(int argc, char *argv[])
2845 static struct option long_options[] = {
2846 {"pgdata", required_argument, NULL, 'D'},
2847 {"encoding", required_argument, NULL, 'E'},
2848 {"locale", required_argument, NULL, 1},
2849 {"lc-collate", required_argument, NULL, 2},
2850 {"lc-ctype", required_argument, NULL, 3},
2851 {"lc-monetary", required_argument, NULL, 4},
2852 {"lc-numeric", required_argument, NULL, 5},
2853 {"lc-time", required_argument, NULL, 6},
2854 {"lc-messages", required_argument, NULL, 7},
2855 {"no-locale", no_argument, NULL, 8},
2856 {"text-search-config", required_argument, NULL, 'T'},
2857 {"auth", required_argument, NULL, 'A'},
2858 {"auth-local", required_argument, NULL, 10},
2859 {"auth-host", required_argument, NULL, 11},
2860 {"pwprompt", no_argument, NULL, 'W'},
2861 {"pwfile", required_argument, NULL, 9},
2862 {"username", required_argument, NULL, 'U'},
2863 {"help", no_argument, NULL, '?'},
2864 {"version", no_argument, NULL, 'V'},
2865 {"debug", no_argument, NULL, 'd'},
2866 {"show", no_argument, NULL, 's'},
2867 {"noclean", no_argument, NULL, 'n'}, /* for backwards compatibility */
2868 {"no-clean", no_argument, NULL, 'n'},
2869 {"nosync", no_argument, NULL, 'N'}, /* for backwards compatibility */
2870 {"no-sync", no_argument, NULL, 'N'},
2871 {"no-instructions", no_argument, NULL, 13},
2872 {"sync-only", no_argument, NULL, 'S'},
2873 {"waldir", required_argument, NULL, 'X'},
2874 {"wal-segsize", required_argument, NULL, 12},
2875 {"data-checksums", no_argument, NULL, 'k'},
2876 {"allow-group-access", no_argument, NULL, 'g'},
2877 {"discard-caches", no_argument, NULL, 14},
2878 {NULL, 0, NULL, 0}
2882 * options with no short version return a low integer, the rest return
2883 * their short version value
2885 int c;
2886 int option_index;
2887 char *effective_user;
2888 PQExpBuffer start_db_cmd;
2889 char pg_ctl_path[MAXPGPATH];
2892 * Ensure that buffering behavior of stdout matches what it is in
2893 * interactive usage (at least on most platforms). This prevents
2894 * unexpected output ordering when, eg, output is redirected to a file.
2895 * POSIX says we must do this before any other usage of these files.
2897 setvbuf(stdout, NULL, PG_IOLBF, 0);
2899 pg_logging_init(argv[0]);
2900 progname = get_progname(argv[0]);
2901 set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("initdb"));
2903 if (argc > 1)
2905 if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
2907 usage(progname);
2908 exit(0);
2910 if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
2912 puts("initdb (PostgreSQL) " PG_VERSION);
2913 exit(0);
2917 /* process command-line options */
2919 while ((c = getopt_long(argc, argv, "A:dD:E:gkL:nNsST:U:WX:", long_options, &option_index)) != -1)
2921 switch (c)
2923 case 'A':
2924 authmethodlocal = authmethodhost = pg_strdup(optarg);
2927 * When ident is specified, use peer for local connections.
2928 * Mirrored, when peer is specified, use ident for TCP/IP
2929 * connections.
2931 if (strcmp(authmethodhost, "ident") == 0)
2932 authmethodlocal = "peer";
2933 else if (strcmp(authmethodlocal, "peer") == 0)
2934 authmethodhost = "ident";
2935 break;
2936 case 10:
2937 authmethodlocal = pg_strdup(optarg);
2938 break;
2939 case 11:
2940 authmethodhost = pg_strdup(optarg);
2941 break;
2942 case 'D':
2943 pg_data = pg_strdup(optarg);
2944 break;
2945 case 'E':
2946 encoding = pg_strdup(optarg);
2947 break;
2948 case 'W':
2949 pwprompt = true;
2950 break;
2951 case 'U':
2952 username = pg_strdup(optarg);
2953 break;
2954 case 'd':
2955 debug = true;
2956 printf(_("Running in debug mode.\n"));
2957 break;
2958 case 'n':
2959 noclean = true;
2960 printf(_("Running in no-clean mode. Mistakes will not be cleaned up.\n"));
2961 break;
2962 case 'N':
2963 do_sync = false;
2964 break;
2965 case 'S':
2966 sync_only = true;
2967 break;
2968 case 'k':
2969 data_checksums = true;
2970 break;
2971 case 'L':
2972 share_path = pg_strdup(optarg);
2973 break;
2974 case 1:
2975 locale = pg_strdup(optarg);
2976 break;
2977 case 2:
2978 lc_collate = pg_strdup(optarg);
2979 break;
2980 case 3:
2981 lc_ctype = pg_strdup(optarg);
2982 break;
2983 case 4:
2984 lc_monetary = pg_strdup(optarg);
2985 break;
2986 case 5:
2987 lc_numeric = pg_strdup(optarg);
2988 break;
2989 case 6:
2990 lc_time = pg_strdup(optarg);
2991 break;
2992 case 7:
2993 lc_messages = pg_strdup(optarg);
2994 break;
2995 case 8:
2996 locale = "C";
2997 break;
2998 case 9:
2999 pwfilename = pg_strdup(optarg);
3000 break;
3001 case 's':
3002 show_setting = true;
3003 break;
3004 case 'T':
3005 default_text_search_config = pg_strdup(optarg);
3006 break;
3007 case 'X':
3008 xlog_dir = pg_strdup(optarg);
3009 break;
3010 case 12:
3011 str_wal_segment_size_mb = pg_strdup(optarg);
3012 break;
3013 case 13:
3014 noinstructions = true;
3015 break;
3016 case 'g':
3017 SetDataDirectoryCreatePerm(PG_DIR_MODE_GROUP);
3018 break;
3019 case 14:
3020 extra_options = psprintf("%s %s",
3021 extra_options,
3022 "-c debug_discard_caches=1");
3023 break;
3024 default:
3025 /* getopt_long already emitted a complaint */
3026 fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
3027 progname);
3028 exit(1);
3034 * Non-option argument specifies data directory as long as it wasn't
3035 * already specified with -D / --pgdata
3037 if (optind < argc && !pg_data)
3039 pg_data = pg_strdup(argv[optind]);
3040 optind++;
3043 if (optind < argc)
3045 pg_log_error("too many command-line arguments (first is \"%s\")",
3046 argv[optind]);
3047 fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
3048 progname);
3049 exit(1);
3052 atexit(cleanup_directories_atexit);
3054 /* If we only need to fsync, just do it and exit */
3055 if (sync_only)
3057 setup_pgdata();
3059 /* must check that directory is readable */
3060 if (pg_check_dir(pg_data) <= 0)
3062 pg_log_error("could not access directory \"%s\": %m", pg_data);
3063 exit(1);
3066 fputs(_("syncing data to disk ... "), stdout);
3067 fflush(stdout);
3068 fsync_pgdata(pg_data, PG_VERSION_NUM);
3069 check_ok();
3070 return 0;
3073 if (pwprompt && pwfilename)
3075 pg_log_error("password prompt and password file cannot be specified together");
3076 exit(1);
3079 check_authmethod_unspecified(&authmethodlocal);
3080 check_authmethod_unspecified(&authmethodhost);
3082 check_authmethod_valid(authmethodlocal, auth_methods_local, "local");
3083 check_authmethod_valid(authmethodhost, auth_methods_host, "host");
3085 check_need_password(authmethodlocal, authmethodhost);
3087 /* set wal segment size */
3088 if (str_wal_segment_size_mb == NULL)
3089 wal_segment_size_mb = (DEFAULT_XLOG_SEG_SIZE) / (1024 * 1024);
3090 else
3092 char *endptr;
3094 /* check that the argument is a number */
3095 wal_segment_size_mb = strtol(str_wal_segment_size_mb, &endptr, 10);
3097 /* verify that wal segment size is valid */
3098 if (endptr == str_wal_segment_size_mb || *endptr != '\0')
3100 pg_log_error("argument of --wal-segsize must be a number");
3101 exit(1);
3103 if (!IsValidWalSegSize(wal_segment_size_mb * 1024 * 1024))
3105 pg_log_error("argument of --wal-segsize must be a power of 2 between 1 and 1024");
3106 exit(1);
3110 get_restricted_token();
3112 setup_pgdata();
3114 setup_bin_paths(argv[0]);
3116 effective_user = get_id();
3117 if (!username)
3118 username = effective_user;
3120 if (strncmp(username, "pg_", 3) == 0)
3122 pg_log_error("superuser name \"%s\" is disallowed; role names cannot begin with \"pg_\"", username);
3123 exit(1);
3126 printf(_("The files belonging to this database system will be owned "
3127 "by user \"%s\".\n"
3128 "This user must also own the server process.\n\n"),
3129 effective_user);
3131 set_info_version();
3133 setup_data_file_paths();
3135 setup_locale_encoding();
3137 setup_text_search();
3139 printf("\n");
3141 if (data_checksums)
3142 printf(_("Data page checksums are enabled.\n"));
3143 else
3144 printf(_("Data page checksums are disabled.\n"));
3146 if (pwprompt || pwfilename)
3147 get_su_pwd();
3149 printf("\n");
3151 initialize_data_directory();
3153 if (do_sync)
3155 fputs(_("syncing data to disk ... "), stdout);
3156 fflush(stdout);
3157 fsync_pgdata(pg_data, PG_VERSION_NUM);
3158 check_ok();
3160 else
3161 printf(_("\nSync to disk skipped.\nThe data directory might become corrupt if the operating system crashes.\n"));
3163 if (authwarning)
3165 printf("\n");
3166 pg_log_warning("enabling \"trust\" authentication for local connections");
3167 fprintf(stderr, _("You can change this by editing pg_hba.conf or using the option -A, or\n"
3168 "--auth-local and --auth-host, the next time you run initdb.\n"));
3171 if (!noinstructions)
3174 * Build up a shell command to tell the user how to start the server
3176 start_db_cmd = createPQExpBuffer();
3178 /* Get directory specification used to start initdb ... */
3179 strlcpy(pg_ctl_path, argv[0], sizeof(pg_ctl_path));
3180 canonicalize_path(pg_ctl_path);
3181 get_parent_directory(pg_ctl_path);
3182 /* ... and tag on pg_ctl instead */
3183 join_path_components(pg_ctl_path, pg_ctl_path, "pg_ctl");
3185 /* Convert the path to use native separators */
3186 make_native_path(pg_ctl_path);
3188 /* path to pg_ctl, properly quoted */
3189 appendShellString(start_db_cmd, pg_ctl_path);
3191 /* add -D switch, with properly quoted data directory */
3192 appendPQExpBufferStr(start_db_cmd, " -D ");
3193 appendShellString(start_db_cmd, pgdata_native);
3195 /* add suggested -l switch and "start" command */
3196 /* translator: This is a placeholder in a shell command. */
3197 appendPQExpBuffer(start_db_cmd, " -l %s start", _("logfile"));
3199 printf(_("\nSuccess. You can now start the database server using:\n\n"
3200 " %s\n\n"),
3201 start_db_cmd->data);
3203 destroyPQExpBuffer(start_db_cmd);
3207 success = true;
3208 return 0;