4242 * Portions Copyright (c) 1994, Regents of the University of California
4343 * Portions taken from FreeBSD.
4444 *
45- * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.127 2007/01/05 22: 19:47 momjian Exp $
45+ * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.128 2007/01/06 19:40:00 momjian Exp $
4646 *
4747 *-------------------------------------------------------------------------
4848 */
@@ -95,6 +95,7 @@ static char *authmethod = "";
9595static bool debug = false;
9696static bool noclean = false;
9797static bool show_setting = false;
98+ static char * xlog_dir = "" ;
9899
99100
100101/* internal vars */
@@ -112,6 +113,8 @@ static char *features_file;
112113static char * system_views_file ;
113114static bool made_new_pgdata = false;
114115static bool found_existing_pgdata = false;
116+ static bool made_new_xlogdir = false;
117+ static bool found_existing_xlogdir = false;
115118static char infoversion [100 ];
116119static bool caught_signal = false;
117120static bool output_failed = false;
@@ -163,7 +166,7 @@ static void exit_nicely(void);
163166static char * get_id (void );
164167static char * get_encoding_id (char * encoding_name );
165168static char * get_short_version (void );
166- static int check_data_dir (void );
169+ static int check_data_dir (char * dir );
167170static bool mkdatadir (const char * subdir );
168171static void set_input (char * * dest ,char * filename );
169172static void check_input (char * path );
@@ -610,6 +613,24 @@ exit_nicely(void)
610613fprintf (stderr ,_ ("%s: failed to remove contents of data directory\n" ),
611614progname );
612615}
616+
617+ if (made_new_xlogdir )
618+ {
619+ fprintf (stderr ,_ ("%s: removing transaction log directory \"%s\"\n" ),
620+ progname ,xlog_dir );
621+ if (!rmtree (xlog_dir , true))
622+ fprintf (stderr ,_ ("%s: failed to remove transaction log directory\n" ),
623+ progname );
624+ }
625+ else if (found_existing_xlogdir )
626+ {
627+ fprintf (stderr ,
628+ _ ("%s: removing contents of transaction log directory \"%s\"\n" ),
629+ progname ,xlog_dir );
630+ if (!rmtree (xlog_dir , false))
631+ fprintf (stderr ,_ ("%s: failed to remove contents of transaction log directory\n" ),
632+ progname );
633+ }
613634/* otherwise died during startup, do nothing! */
614635}
615636else
@@ -618,6 +639,11 @@ exit_nicely(void)
618639fprintf (stderr ,
619640_ ("%s: data directory \"%s\" not removed at user's request\n" ),
620641progname ,pg_data );
642+
643+ if (made_new_xlogdir || found_existing_xlogdir )
644+ fprintf (stderr ,
645+ _ ("%s: transaction log directory \"%s\" not removed at user's request\n" ),
646+ progname ,xlog_dir );
621647}
622648
623649exit (1 );
@@ -919,21 +945,21 @@ get_short_version(void)
919945}
920946
921947/*
922- * make sure thedata directory either doesn't exist or is empty
948+ * make sure the directory either doesn't exist or is empty
923949 *
924950 * Returns 0 if nonexistent, 1 if exists and empty, 2 if not empty,
925951 * or -1 if trouble accessing directory
926952 */
927953static int
928- check_data_dir (void )
954+ check_data_dir (char * dir )
929955{
930956DIR * chkdir ;
931957struct dirent * file ;
932958int result = 1 ;
933959
934960errno = 0 ;
935961
936- chkdir = opendir (pg_data );
962+ chkdir = opendir (dir );
937963
938964if (!chkdir )
939965return (errno == ENOENT ) ?0 :-1 ;
@@ -2354,6 +2380,7 @@ usage(const char *progname)
23542380" in the respective category (default taken from\n"
23552381" environment)\n" ));
23562382printf (_ (" --no-locale equivalent to --locale=C\n" ));
2383+ printf (_ (" -X, --xlogdir=XLOGDIR location for the transaction log directory\n" ));
23572384printf (_ (" -A, --auth=METHOD default authentication method for local connections\n" ));
23582385printf (_ (" -U, --username=NAME database superuser name\n" ));
23592386printf (_ (" -W, --pwprompt prompt for a password for the new superuser\n" ));
@@ -2397,6 +2424,7 @@ main(int argc, char *argv[])
23972424{"debug" ,no_argument ,NULL ,'d' },
23982425{"show" ,no_argument ,NULL ,'s' },
23992426{"noclean" ,no_argument ,NULL ,'n' },
2427+ {"xlogdir" ,required_argument ,NULL ,'X' },
24002428{NULL ,0 ,NULL ,0 }
24012429};
24022430
@@ -2447,7 +2475,7 @@ main(int argc, char *argv[])
24472475
24482476/* process command-line options */
24492477
2450- while ((c = getopt_long (argc ,argv ,"dD:E:L:nU:WA:s " ,long_options ,& option_index ))!= -1 )
2478+ while ((c = getopt_long (argc ,argv ,"dD:E:L:nU:WA:sX: " ,long_options ,& option_index ))!= -1 )
24512479{
24522480switch (c )
24532481{
@@ -2507,6 +2535,9 @@ main(int argc, char *argv[])
25072535case 's' :
25082536show_setting = true;
25092537break ;
2538+ case 'X' :
2539+ xlog_dir = xstrdup (optarg );
2540+ break ;
25102541default :
25112542/* getopt_long already emitted a complaint */
25122543fprintf (stderr ,_ ("Try \"%s --help\" for more information.\n" ),
@@ -2836,7 +2867,7 @@ main(int argc, char *argv[])
28362867pqsignal (SIGPIPE ,SIG_IGN );
28372868#endif
28382869
2839- switch (check_data_dir ())
2870+ switch (check_data_dir (pg_data ))
28402871{
28412872case 0 :
28422873/* PGDATA not there, must create it */
@@ -2887,6 +2918,82 @@ main(int argc, char *argv[])
28872918exit_nicely ();
28882919}
28892920
2921+ /* Create transaction log symlink, if required */
2922+ if (strcmp (xlog_dir ,"" )!= 0 )
2923+ {
2924+ char * linkloc ;
2925+
2926+ linkloc = (char * )palloc (strlen (pg_data )+ 8 + 2 );
2927+ sprintf (linkloc ,"%s/pg_xlog" ,pg_data );
2928+
2929+ /* check if the specified xlog directory is empty */
2930+ switch (check_data_dir (xlog_dir ))
2931+ {
2932+ case 0 :
2933+ /* xlog directory not there, must create it */
2934+ printf (_ ("creating directory %s ... " ),
2935+ xlog_dir );
2936+ fflush (stdout );
2937+
2938+ if (mkdir_p (xlog_dir ,0700 )!= 0 )
2939+ {
2940+ fprintf (stderr ,_ ("%s: could not create directory \"%s\": %s\n" ),
2941+ progname ,xlog_dir ,strerror (errno ));
2942+ exit_nicely ();
2943+ }
2944+ else
2945+ {
2946+ check_ok ();
2947+ }
2948+
2949+ made_new_xlogdir = true;
2950+ break ;
2951+ case 1 :
2952+ /* Present but empty, fix permissions and use it */
2953+ printf (_ ("fixing permissions on existing directory %s ... " ),
2954+ xlog_dir );
2955+ fflush (stdout );
2956+
2957+ if (chmod (xlog_dir ,0700 )!= 0 )
2958+ {
2959+ fprintf (stderr ,_ ("%s: could not change permissions of directory \"%s\": %s\n" ),
2960+ progname ,xlog_dir ,strerror (errno ));
2961+ exit_nicely ();
2962+ }
2963+ else
2964+ check_ok ();
2965+
2966+ found_existing_xlogdir = true;
2967+ break ;
2968+ case 2 :
2969+ /* Present and not empty */
2970+ fprintf (stderr ,
2971+ _ ("%s: directory \"%s\" exists but is not empty\n"
2972+ "If you want to store the transaction log there, either\n"
2973+ "remove or empty the directory \"%s\".\n" ),
2974+ progname ,xlog_dir ,xlog_dir );
2975+ exit (1 );/* no further message needed */
2976+
2977+ default :
2978+ /* Trouble accessing directory */
2979+ fprintf (stderr ,_ ("%s: could not access directory \"%s\": %s\n" ),
2980+ progname ,xlog_dir ,strerror (errno ));
2981+ exit_nicely ();
2982+ }
2983+
2984+ #ifdef HAVE_SYMLINK
2985+ if (symlink (xlog_dir ,linkloc )!= 0 )
2986+ {
2987+ fprintf (stderr ,_ ("%s: could not create symbolic link \"%s\": %s\n" ),
2988+ progname ,linkloc ,strerror (errno ));
2989+ exit_nicely ();
2990+ }
2991+ #else
2992+ fprintf (stderr ,_ ("%s: symlinks are not supported on this plataform" ));
2993+ exit_nicely ();
2994+ #endif
2995+ }
2996+
28902997/* Create required subdirectories */
28912998printf (_ ("creating subdirectories ... " ));
28922999fflush (stdout );