*** ./doc/src/sgml/ref/initdb.sgml.orig 2006-09-15 21:30:18.000000000 -0300 --- ./doc/src/sgml/ref/initdb.sgml 2007-01-03 23:34:13.000000000 -0200 *************** *** 177,182 **** --- 177,193 ---- + + + + + This option specifies the directory where the transaction log + should be stored. This option is only supported on systems that support symbolic links. + + + + + *** ./src/bin/initdb/initdb.c.orig 2006-12-22 22:43:12.000000000 -0200 --- ./src/bin/initdb/initdb.c 2007-01-03 23:34:45.000000000 -0200 *************** *** 95,100 **** --- 95,101 ---- static bool debug = false; static bool noclean = false; static bool show_setting = false; + static char *xlog_dir = ""; /* internal vars */ *************** *** 112,117 **** --- 113,120 ---- static char *system_views_file; static bool made_new_pgdata = false; static bool found_existing_pgdata = false; + static bool made_new_xlogdir = false; + static bool found_existing_xlogdir = false; static char infoversion[100]; static bool caught_signal = false; static bool output_failed = false; *************** *** 163,169 **** static char *get_id(void); static char *get_encoding_id(char *encoding_name); static char *get_short_version(void); ! static int check_data_dir(void); static bool mkdatadir(const char *subdir); static void set_input(char **dest, char *filename); static void check_input(char *path); --- 166,172 ---- static char *get_id(void); static char *get_encoding_id(char *encoding_name); static char *get_short_version(void); ! static int check_data_dir(char *dir); static bool mkdatadir(const char *subdir); static void set_input(char **dest, char *filename); static void check_input(char *path); *************** *** 610,615 **** --- 613,636 ---- fprintf(stderr, _("%s: failed to remove contents of data directory\n"), progname); } + + if (made_new_xlogdir) + { + fprintf(stderr, _("%s: removing transaction log directory \"%s\"\n"), + progname, xlog_dir); + if (!rmtree(xlog_dir, true)) + fprintf(stderr, _("%s: failed to remove transaction log directory\n"), + progname); + } + else if (found_existing_xlogdir) + { + fprintf(stderr, + _("%s: removing contents of transaction log directory \"%s\"\n"), + progname, xlog_dir); + if (!rmtree(xlog_dir, false)) + fprintf(stderr, _("%s: failed to remove contents of transaction log directory\n"), + progname); + } /* otherwise died during startup, do nothing! */ } else *************** *** 618,623 **** --- 639,649 ---- fprintf(stderr, _("%s: data directory \"%s\" not removed at user's request\n"), progname, pg_data); + + if (made_new_xlogdir || found_existing_xlogdir) + fprintf(stderr, + _("%s: transaction log directory \"%s\" not removed at user's request\n"), + progname, xlog_dir); } exit(1); *************** *** 919,931 **** } /* ! * make sure the data directory either doesn't exist or is empty * * Returns 0 if nonexistent, 1 if exists and empty, 2 if not empty, * or -1 if trouble accessing directory */ static int ! check_data_dir(void) { DIR *chkdir; struct dirent *file; --- 945,957 ---- } /* ! * make sure the directory either doesn't exist or is empty * * Returns 0 if nonexistent, 1 if exists and empty, 2 if not empty, * or -1 if trouble accessing directory */ static int ! check_data_dir(char *dir) { DIR *chkdir; struct dirent *file; *************** *** 933,939 **** errno = 0; ! chkdir = opendir(pg_data); if (!chkdir) return (errno == ENOENT) ? 0 : -1; --- 959,965 ---- errno = 0; ! chkdir = opendir(dir); if (!chkdir) return (errno == ENOENT) ? 0 : -1; *************** *** 2354,2359 **** --- 2380,2386 ---- " in the respective category (default taken from\n" " environment)\n")); printf(_(" --no-locale equivalent to --locale=C\n")); + printf(_(" -X, --xlogdir=XLOGDIR location for the transaction log directory\n")); printf(_(" -A, --auth=METHOD default authentication method for local connections\n")); printf(_(" -U, --username=NAME database superuser name\n")); printf(_(" -W, --pwprompt prompt for a password for the new superuser\n")); *************** *** 2397,2402 **** --- 2424,2430 ---- {"debug", no_argument, NULL, 'd'}, {"show", no_argument, NULL, 's'}, {"noclean", no_argument, NULL, 'n'}, + {"xlogdir", required_argument, NULL, 'X'}, {NULL, 0, NULL, 0} }; *************** *** 2447,2453 **** /* process command-line options */ ! while ((c = getopt_long(argc, argv, "dD:E:L:nU:WA:s", long_options, &option_index)) != -1) { switch (c) { --- 2475,2481 ---- /* process command-line options */ ! while ((c = getopt_long(argc, argv, "dD:E:L:nU:WA:sX:", long_options, &option_index)) != -1) { switch (c) { *************** *** 2507,2512 **** --- 2535,2543 ---- case 's': show_setting = true; break; + case 'X': + xlog_dir = xstrdup(optarg); + break; default: /* getopt_long already emitted a complaint */ fprintf(stderr, _("Try \"%s --help\" for more information.\n"), *************** *** 2836,2842 **** pqsignal(SIGPIPE, SIG_IGN); #endif ! switch (check_data_dir()) { case 0: /* PGDATA not there, must create it */ --- 2867,2873 ---- pqsignal(SIGPIPE, SIG_IGN); #endif ! switch (check_data_dir(pg_data)) { case 0: /* PGDATA not there, must create it */ *************** *** 2887,2892 **** --- 2918,2999 ---- exit_nicely(); } + /* Create transaction log symlink, if required */ + if (strcmp(xlog_dir, "") != 0) + { + char *linkloc; + + linkloc = (char *) palloc(strlen(pg_data) + 8 + 2); + sprintf(linkloc, "%s/pg_xlog", pg_data); + + /* check if the specified xlog directory is empty */ + switch (check_data_dir(xlog_dir)) + { + case 0: + /* xlog directory not there, must create it */ + printf(_("creating directory %s ... "), + xlog_dir); + fflush(stdout); + + if (mkdir_p(xlog_dir, 0700) != 0) + { + fprintf(stderr, _("%s: could not create directory \"%s\": %s\n"), + progname, xlog_dir, strerror(errno)); + exit_nicely(); + } + else + { + check_ok(); + } + + made_new_xlogdir = true; + break; + case 1: + /* Present but empty, fix permissions and use it */ + printf(_("fixing permissions on existing directory %s ... "), + xlog_dir); + fflush(stdout); + + if (chmod(xlog_dir, 0700) != 0) + { + fprintf(stderr, _("%s: could not change permissions of directory \"%s\": %s\n"), + progname, xlog_dir, strerror(errno)); + exit_nicely(); + } + else + check_ok(); + + found_existing_xlogdir = true; + break; + case 2: + /* Present and not empty */ + fprintf(stderr, + _("%s: directory \"%s\" exists but is not empty\n" + "If you want to store the transaction log there, either\n" + "remove or empty the directory \"%s\".\n"), + progname, xlog_dir, xlog_dir); + exit(1); /* no further message needed */ + + default: + /* Trouble accessing directory */ + fprintf(stderr, _("%s: could not access directory \"%s\": %s\n"), + progname, xlog_dir, strerror(errno)); + exit_nicely(); + } + + #ifdef HAVE_SYMLINK + if (symlink(xlog_dir, linkloc) != 0) + { + fprintf(stderr, _("%s: could not create symbolic link \"%s\": %s\n"), + progname, linkloc, strerror(errno)); + exit_nicely(); + } + #else + fprintf(stderr, _("%s: symlinks are not supported on this plataform")); + exit_nicely(); + #endif + } + /* Create required subdirectories */ printf(_("creating subdirectories ... ")); fflush(stdout);