LCOV - differential code coverage report
Current view: top level - src/bin/pg_upgrade - option.c (source / functions) Coverage Total Hit UIC GIC
Current: c70b6db34ffeab48beef1fb4ce61bcad3772b8dd vs 06473f5a344df8c9594ead90a609b86f6724cff8 Lines: 61.4 % 233 143 90 143
Current Date: 2025-09-06 07:49:51 +0900 Functions: 100.0 % 5 5 5
Baseline: lcov-20250906-005545-baseline Branches: 37.3 % 110 41 69 41
Baseline Date: 2025-09-05 08:21:35 +0100 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(30,360] days: 66.7 % 18 12 6 12
(360..) days: 60.9 % 215 131 84 131
Function coverage date bins:
(360..) days: 100.0 % 5 5 5
Branch coverage date bins:
(30,360] days: 25.0 % 4 1 3 1
(360..) days: 37.7 % 106 40 66 40

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*
                                  2                 :                :  *  option.c
                                  3                 :                :  *
                                  4                 :                :  *  options functions
                                  5                 :                :  *
                                  6                 :                :  *  Copyright (c) 2010-2025, PostgreSQL Global Development Group
                                  7                 :                :  *  src/bin/pg_upgrade/option.c
                                  8                 :                :  */
                                  9                 :                : 
                                 10                 :                : #include "postgres_fe.h"
                                 11                 :                : 
                                 12                 :                : #ifdef WIN32
                                 13                 :                : #include <io.h>
                                 14                 :                : #endif
                                 15                 :                : 
                                 16                 :                : #include "common/string.h"
                                 17                 :                : #include "fe_utils/option_utils.h"
                                 18                 :                : #include "getopt_long.h"
                                 19                 :                : #include "pg_upgrade.h"
                                 20                 :                : #include "utils/pidfile.h"
                                 21                 :                : 
                                 22                 :                : static void usage(void);
                                 23                 :                : static void check_required_directory(char **dirpath,
                                 24                 :                :                                      const char *envVarName, bool useCwd,
                                 25                 :                :                                      const char *cmdLineOption, const char *description,
                                 26                 :                :                                      bool missingOk);
                                 27                 :                : #define FIX_DEFAULT_READ_ONLY "-c default_transaction_read_only=false"
                                 28                 :                : 
                                 29                 :                : 
                                 30                 :                : UserOpts    user_opts;
                                 31                 :                : 
                                 32                 :                : 
                                 33                 :                : /*
                                 34                 :                :  * parseCommandLine()
                                 35                 :                :  *
                                 36                 :                :  *  Parses the command line (argc, argv[]) and loads structures
                                 37                 :                :  */
                                 38                 :                : void
 5436 bruce@momjian.us           39                 :GIC          21 : parseCommandLine(int argc, char *argv[])
                                 40                 :                : {
                                 41                 :                :     static struct option long_options[] = {
                                 42                 :                :         {"old-datadir", required_argument, NULL, 'd'},
                                 43                 :                :         {"new-datadir", required_argument, NULL, 'D'},
                                 44                 :                :         {"old-bindir", required_argument, NULL, 'b'},
                                 45                 :                :         {"new-bindir", required_argument, NULL, 'B'},
                                 46                 :                :         {"no-sync", no_argument, NULL, 'N'},
                                 47                 :                :         {"old-options", required_argument, NULL, 'o'},
                                 48                 :                :         {"new-options", required_argument, NULL, 'O'},
                                 49                 :                :         {"old-port", required_argument, NULL, 'p'},
                                 50                 :                :         {"new-port", required_argument, NULL, 'P'},
                                 51                 :                : 
                                 52                 :                :         {"username", required_argument, NULL, 'U'},
                                 53                 :                :         {"check", no_argument, NULL, 'c'},
                                 54                 :                :         {"link", no_argument, NULL, 'k'},
                                 55                 :                :         {"retain", no_argument, NULL, 'r'},
                                 56                 :                :         {"jobs", required_argument, NULL, 'j'},
                                 57                 :                :         {"socketdir", required_argument, NULL, 's'},
                                 58                 :                :         {"verbose", no_argument, NULL, 'v'},
                                 59                 :                :         {"clone", no_argument, NULL, 1},
                                 60                 :                :         {"copy", no_argument, NULL, 2},
                                 61                 :                :         {"copy-file-range", no_argument, NULL, 3},
                                 62                 :                :         {"sync-method", required_argument, NULL, 4},
                                 63                 :                :         {"no-statistics", no_argument, NULL, 5},
                                 64                 :                :         {"set-char-signedness", required_argument, NULL, 6},
                                 65                 :                :         {"swap", no_argument, NULL, 7},
                                 66                 :                : 
                                 67                 :                :         {NULL, 0, NULL, 0}
                                 68                 :                :     };
                                 69                 :                :     int         option;         /* Command line option */
 5596                            70                 :             21 :     int         optindex = 0;   /* used by getopt_long */
                                 71                 :                :     int         os_user_effective_id;
                                 72                 :                :     DataDirSyncMethod unused;
                                 73                 :                : 
 1358 michael@paquier.xyz        74                 :             21 :     user_opts.do_sync = true;
 5227 bruce@momjian.us           75                 :             21 :     user_opts.transfer_mode = TRANSFER_MODE_COPY;
  198 jdavis@postgresql.or       76                 :             21 :     user_opts.do_statistics = true;
  197 msawada@postgresql.o       77                 :             21 :     user_opts.char_signedness = -1;
                                 78                 :                : 
 5436 bruce@momjian.us           79                 :             21 :     os_info.progname = get_progname(argv[0]);
                                 80                 :                : 
                                 81                 :                :     /* Process libpq env. variables; load values here for usage() output */
 5181                            82         [ -  + ]:             21 :     old_cluster.port = getenv("PGPORTOLD") ? atoi(getenv("PGPORTOLD")) : DEF_PGUPORT;
                                 83         [ -  + ]:             21 :     new_cluster.port = getenv("PGPORTNEW") ? atoi(getenv("PGPORTNEW")) : DEF_PGUPORT;
                                 84                 :                : 
 5227                            85                 :             21 :     os_user_effective_id = get_user_info(&os_info.user);
                                 86                 :                :     /* we override just the database user name;  we got the OS id above */
                                 87         [ -  + ]:             21 :     if (getenv("PGUSER"))
                                 88                 :                :     {
 5227 bruce@momjian.us           89                 :UIC           0 :         pg_free(os_info.user);
                                 90                 :                :         /* must save value, getenv()'s pointer is not stable */
                                 91                 :              0 :         os_info.user = pg_strdup(getenv("PGUSER"));
                                 92                 :                :     }
                                 93                 :                : 
 5596 bruce@momjian.us           94         [ +  - ]:GIC          21 :     if (argc > 1)
                                 95                 :                :     {
 4453                            96   [ +  +  -  + ]:             21 :         if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
                                 97                 :                :         {
 5436                            98                 :              1 :             usage();
 5267 peter_e@gmx.net            99                 :              1 :             exit(0);
                                100                 :                :         }
 5596 bruce@momjian.us          101   [ +  +  -  + ]:             20 :         if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
                                102                 :                :         {
 5233 peter_e@gmx.net           103                 :              1 :             puts("pg_upgrade (PostgreSQL) " PG_VERSION);
 5267                           104                 :              1 :             exit(0);
                                105                 :                :         }
                                106                 :                :     }
                                107                 :                : 
                                108                 :                :     /* Allow help and version to be run as root, so do the test here. */
 5227 bruce@momjian.us          109         [ -  + ]:             19 :     if (os_user_effective_id == 0)
 1152 tgl@sss.pgh.pa.us         110                 :UIC           0 :         pg_fatal("%s: cannot be run as root", os_info.progname);
                                111                 :                : 
  999 peter@eisentraut.org      112                 :GIC         188 :     while ((option = getopt_long(argc, argv, "b:B:cd:D:j:kNo:O:p:P:rs:U:v",
 5596 bruce@momjian.us          113         [ +  + ]:            188 :                                  long_options, &optindex)) != -1)
                                114                 :                :     {
                                115   [ +  +  +  +  :            170 :         switch (option)
                                     +  -  +  +  -  
                                     -  +  +  -  +  
                                     -  -  +  +  +  
                                        -  -  +  +  
                                                 + ]
                                116                 :                :         {
                                117                 :             18 :             case 'b':
 5436                           118                 :             18 :                 old_cluster.bindir = pg_strdup(optarg);
 5596                           119                 :             18 :                 break;
                                120                 :                : 
                                121                 :             18 :             case 'B':
 5436                           122                 :             18 :                 new_cluster.bindir = pg_strdup(optarg);
 5596                           123                 :             18 :                 break;
                                124                 :                : 
                                125                 :              6 :             case 'c':
 5436                           126                 :              6 :                 user_opts.check = true;
 5596                           127                 :              6 :                 break;
                                128                 :                : 
 5227                           129                 :             18 :             case 'd':
                                130                 :             18 :                 old_cluster.pgdata = pg_strdup(optarg);
                                131                 :             18 :                 break;
                                132                 :                : 
                                133                 :             18 :             case 'D':
                                134                 :             18 :                 new_cluster.pgdata = pg_strdup(optarg);
                                135                 :             18 :                 break;
                                136                 :                : 
 4637 bruce@momjian.us          137                 :UIC           0 :             case 'j':
                                138                 :              0 :                 user_opts.jobs = atoi(optarg);
                                139                 :              0 :                 break;
                                140                 :                : 
 5596 bruce@momjian.us          141                 :GIC           1 :             case 'k':
 5436                           142                 :              1 :                 user_opts.transfer_mode = TRANSFER_MODE_LINK;
 5596                           143                 :              1 :                 break;
                                144                 :                : 
 1358 michael@paquier.xyz       145                 :             18 :             case 'N':
                                146                 :             18 :                 user_opts.do_sync = false;
                                147                 :             18 :                 break;
                                148                 :                : 
 5080 bruce@momjian.us          149                 :UIC           0 :             case 'o':
                                150                 :                :                 /* append option? */
 4030                           151         [ #  # ]:              0 :                 if (!old_cluster.pgopts)
                                152                 :              0 :                     old_cluster.pgopts = pg_strdup(optarg);
                                153                 :                :                 else
                                154                 :                :                 {
 3759                           155                 :              0 :                     char       *old_pgopts = old_cluster.pgopts;
                                156                 :                : 
 4030                           157                 :              0 :                     old_cluster.pgopts = psprintf("%s %s", old_pgopts, optarg);
                                158                 :              0 :                     free(old_pgopts);
                                159                 :                :                 }
 5080                           160                 :              0 :                 break;
                                161                 :                : 
                                162                 :              0 :             case 'O':
                                163                 :                :                 /* append option? */
 4030                           164         [ #  # ]:              0 :                 if (!new_cluster.pgopts)
                                165                 :              0 :                     new_cluster.pgopts = pg_strdup(optarg);
                                166                 :                :                 else
                                167                 :                :                 {
 3759                           168                 :              0 :                     char       *new_pgopts = new_cluster.pgopts;
                                169                 :                : 
 4030                           170                 :              0 :                     new_cluster.pgopts = psprintf("%s %s", new_pgopts, optarg);
                                171                 :              0 :                     free(new_pgopts);
                                172                 :                :                 }
 5080                           173                 :              0 :                 break;
                                174                 :                : 
 5596 bruce@momjian.us          175                 :GIC          18 :             case 'p':
 5436                           176         [ -  + ]:             18 :                 if ((old_cluster.port = atoi(optarg)) <= 0)
 1152 tgl@sss.pgh.pa.us         177                 :UIC           0 :                     pg_fatal("invalid old port number");
 5596 bruce@momjian.us          178                 :GIC          18 :                 break;
                                179                 :                : 
                                180                 :             18 :             case 'P':
 5436                           181         [ -  + ]:             18 :                 if ((new_cluster.port = atoi(optarg)) <= 0)
 1152 tgl@sss.pgh.pa.us         182                 :UIC           0 :                     pg_fatal("invalid new port number");
 5596 bruce@momjian.us          183                 :GIC          18 :                 break;
                                184                 :                : 
 4926 bruce@momjian.us          185                 :UIC           0 :             case 'r':
                                186                 :              0 :                 log_opts.retain = true;
                                187                 :              0 :                 break;
                                188                 :                : 
 2471 tgl@sss.pgh.pa.us         189                 :GIC          18 :             case 's':
                                190                 :             18 :                 user_opts.socketdir = pg_strdup(optarg);
                                191                 :             18 :                 break;
                                192                 :                : 
 4453 bruce@momjian.us          193                 :UIC           0 :             case 'U':
 5436                           194                 :              0 :                 pg_free(os_info.user);
                                195                 :              0 :                 os_info.user = pg_strdup(optarg);
 4453                           196                 :              0 :                 os_info.user_specified = true;
 5596                           197                 :              0 :                 break;
                                198                 :                : 
                                199                 :              0 :             case 'v':
 5435                           200                 :              0 :                 log_opts.verbose = true;
 5596                           201                 :              0 :                 break;
                                202                 :                : 
 2495 peter_e@gmx.net           203                 :GIC           1 :             case 1:
                                204                 :              1 :                 user_opts.transfer_mode = TRANSFER_MODE_CLONE;
                                205                 :              1 :                 break;
                                206                 :                : 
  995 peter@eisentraut.org      207                 :             14 :             case 2:
                                208                 :             14 :                 user_opts.transfer_mode = TRANSFER_MODE_COPY;
                                209                 :             14 :                 break;
                                210                 :                : 
  731 nathan@postgresql.or      211                 :              1 :             case 3:
  549 tmunro@postgresql.or      212                 :              1 :                 user_opts.transfer_mode = TRANSFER_MODE_COPY_FILE_RANGE;
                                213                 :              1 :                 break;
  549 tmunro@postgresql.or      214                 :UIC           0 :             case 4:
  731 nathan@postgresql.or      215         [ #  # ]:              0 :                 if (!parse_sync_method(optarg, &unused))
                                216                 :              0 :                     exit(1);
                                217                 :              0 :                 user_opts.sync_method = pg_strdup(optarg);
                                218                 :              0 :                 break;
                                219                 :                : 
  198 jdavis@postgresql.or      220                 :              0 :             case 5:
                                221                 :              0 :                 user_opts.do_statistics = false;
                                222                 :              0 :                 break;
                                223                 :                : 
  197 msawada@postgresql.o      224                 :GIC           1 :             case 6:
                                225         [ +  - ]:              1 :                 if (pg_strcasecmp(optarg, "signed") == 0)
                                226                 :              1 :                     user_opts.char_signedness = 1;
  197 msawada@postgresql.o      227         [ #  # ]:UIC           0 :                 else if (pg_strcasecmp(optarg, "unsigned") == 0)
                                228                 :              0 :                     user_opts.char_signedness = 0;
                                229                 :                :                 else
                                230                 :              0 :                     pg_fatal("invalid argument for option %s", "--set-char-signedness");
  197 msawada@postgresql.o      231                 :GIC           1 :                 break;
                                232                 :                : 
  165 nathan@postgresql.or      233                 :              1 :             case 7:
                                234                 :              1 :                 user_opts.transfer_mode = TRANSFER_MODE_SWAP;
                                235                 :              1 :                 break;
                                236                 :                : 
 5596 bruce@momjian.us          237                 :              1 :             default:
 2271 peter@eisentraut.org      238                 :              1 :                 fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
                                239                 :                :                         os_info.progname);
                                240                 :              1 :                 exit(1);
                                241                 :                :         }
                                242                 :                :     }
                                243                 :                : 
 2200                           244         [ -  + ]:             18 :     if (optind < argc)
 1152 tgl@sss.pgh.pa.us         245                 :UIC           0 :         pg_fatal("too many command-line arguments (first is \"%s\")", argv[optind]);
                                246                 :                : 
  731 nathan@postgresql.or      247         [ +  - ]:GIC          18 :     if (!user_opts.sync_method)
                                248                 :             18 :         user_opts.sync_method = pg_strdup("fsync");
                                249                 :                : 
 2271 peter@eisentraut.org      250         [ -  + ]:             18 :     if (log_opts.verbose)
 1152 tgl@sss.pgh.pa.us         251                 :UIC           0 :         pg_log(PG_REPORT, "Running in verbose mode");
                                252                 :                : 
 1293 andres@anarazel.de        253                 :GIC          18 :     log_opts.isatty = isatty(fileno(stdout));
                                254                 :                : 
                                255                 :                :     /* Turn off read-only mode;  add prefix to PGOPTIONS? */
 4298 bruce@momjian.us          256         [ -  + ]:             18 :     if (getenv("PGOPTIONS"))
                                257                 :                :     {
 4141 bruce@momjian.us          258                 :UIC           0 :         char       *pgoptions = psprintf("%s %s", FIX_DEFAULT_READ_ONLY,
                                259                 :                :                                          getenv("PGOPTIONS"));
                                260                 :                : 
 1711 tgl@sss.pgh.pa.us         261                 :              0 :         setenv("PGOPTIONS", pgoptions, 1);
 4298 bruce@momjian.us          262                 :              0 :         pfree(pgoptions);
                                263                 :                :     }
                                264                 :                :     else
 1711 tgl@sss.pgh.pa.us         265                 :GIC          18 :         setenv("PGOPTIONS", FIX_DEFAULT_READ_ONLY, 1);
                                266                 :                : 
                                267                 :                :     /* Get values from env if not already set */
 2471                           268                 :             18 :     check_required_directory(&old_cluster.bindir, "PGBINOLD", false,
 2233 peter@eisentraut.org      269                 :             18 :                              "-b", _("old cluster binaries reside"), false);
 2471 tgl@sss.pgh.pa.us         270                 :             18 :     check_required_directory(&new_cluster.bindir, "PGBINNEW", false,
 2233 peter@eisentraut.org      271                 :             18 :                              "-B", _("new cluster binaries reside"), true);
 2471 tgl@sss.pgh.pa.us         272                 :             18 :     check_required_directory(&old_cluster.pgdata, "PGDATAOLD", false,
 2233 peter@eisentraut.org      273                 :             18 :                              "-d", _("old cluster data resides"), false);
 2471 tgl@sss.pgh.pa.us         274                 :             18 :     check_required_directory(&new_cluster.pgdata, "PGDATANEW", false,
 2233 peter@eisentraut.org      275                 :             18 :                              "-D", _("new cluster data resides"), false);
 2471 tgl@sss.pgh.pa.us         276                 :             18 :     check_required_directory(&user_opts.socketdir, "PGSOCKETDIR", true,
 2233 peter@eisentraut.org      277                 :             18 :                              "-s", _("sockets will be created"), false);
                                278                 :                : 
                                279                 :                : #ifdef WIN32
                                280                 :                : 
                                281                 :                :     /*
                                282                 :                :      * On Windows, initdb --sync-only will fail with a "Permission denied"
                                283                 :                :      * error on file pg_upgrade_utility.log if pg_upgrade is run inside the
                                284                 :                :      * new cluster directory, so we do a check here.
                                285                 :                :      */
                                286                 :                :     {
                                287                 :                :         char        cwd[MAXPGPATH],
                                288                 :                :                     new_cluster_pgdata[MAXPGPATH];
                                289                 :                : 
                                290                 :                :         strlcpy(new_cluster_pgdata, new_cluster.pgdata, MAXPGPATH);
                                291                 :                :         canonicalize_path(new_cluster_pgdata);
                                292                 :                : 
                                293                 :                :         if (!getcwd(cwd, MAXPGPATH))
                                294                 :                :             pg_fatal("could not determine current directory");
                                295                 :                :         canonicalize_path(cwd);
                                296                 :                :         if (path_is_prefix_of_path(new_cluster_pgdata, cwd))
                                297                 :                :             pg_fatal("cannot run pg_upgrade from inside the new cluster data directory on Windows");
                                298                 :                :     }
                                299                 :                : #endif
 5596 bruce@momjian.us          300                 :             18 : }
                                301                 :                : 
                                302                 :                : 
                                303                 :                : static void
 5436                           304                 :              1 : usage(void)
                                305                 :                : {
 3249 peter_e@gmx.net           306                 :              1 :     printf(_("pg_upgrade upgrades a PostgreSQL cluster to a different major version.\n\n"));
                                307                 :              1 :     printf(_("Usage:\n"));
                                308                 :              1 :     printf(_("  pg_upgrade [OPTION]...\n\n"));
                                309                 :              1 :     printf(_("Options:\n"));
                                310                 :              1 :     printf(_("  -b, --old-bindir=BINDIR       old cluster executable directory\n"));
 2233 peter@eisentraut.org      311                 :              1 :     printf(_("  -B, --new-bindir=BINDIR       new cluster executable directory (default\n"
                                312                 :                :              "                                same directory as pg_upgrade)\n"));
 3249 peter_e@gmx.net           313                 :              1 :     printf(_("  -c, --check                   check clusters only, don't change any data\n"));
                                314                 :              1 :     printf(_("  -d, --old-datadir=DATADIR     old cluster data directory\n"));
                                315                 :              1 :     printf(_("  -D, --new-datadir=DATADIR     new cluster data directory\n"));
 2034 peter@eisentraut.org      316                 :              1 :     printf(_("  -j, --jobs=NUM                number of simultaneous processes or threads to use\n"));
 3249 peter_e@gmx.net           317                 :              1 :     printf(_("  -k, --link                    link instead of copying files to new cluster\n"));
 1358 michael@paquier.xyz       318                 :              1 :     printf(_("  -N, --no-sync                 do not wait for changes to be written safely to disk\n"));
 3249 peter_e@gmx.net           319                 :              1 :     printf(_("  -o, --old-options=OPTIONS     old cluster options to pass to the server\n"));
                                320                 :              1 :     printf(_("  -O, --new-options=OPTIONS     new cluster options to pass to the server\n"));
                                321                 :              1 :     printf(_("  -p, --old-port=PORT           old cluster port number (default %d)\n"), old_cluster.port);
                                322                 :              1 :     printf(_("  -P, --new-port=PORT           new cluster port number (default %d)\n"), new_cluster.port);
                                323                 :              1 :     printf(_("  -r, --retain                  retain SQL and log files after success\n"));
 2251 peter@eisentraut.org      324                 :              1 :     printf(_("  -s, --socketdir=DIR           socket directory to use (default current dir.)\n"));
 3249 peter_e@gmx.net           325                 :              1 :     printf(_("  -U, --username=NAME           cluster superuser (default \"%s\")\n"), os_info.user);
                                326                 :              1 :     printf(_("  -v, --verbose                 enable verbose internal logging\n"));
                                327                 :              1 :     printf(_("  -V, --version                 display version information, then exit\n"));
 2495                           328                 :              1 :     printf(_("  --clone                       clone instead of copying files to new cluster\n"));
  995 peter@eisentraut.org      329                 :              1 :     printf(_("  --copy                        copy files to new cluster (default)\n"));
  549 tmunro@postgresql.or      330                 :              1 :     printf(_("  --copy-file-range             copy files to new cluster with copy_file_range\n"));
  198 jdavis@postgresql.or      331                 :              1 :     printf(_("  --no-statistics               do not import statistics from old cluster\n"));
  193 michael@paquier.xyz       332                 :              1 :     printf(_("  --set-char-signedness=OPTION  set new cluster char signedness to \"signed\" or\n"
                                333                 :                :              "                                \"unsigned\"\n"));
  165 nathan@postgresql.or      334                 :              1 :     printf(_("  --swap                        move data directories to new cluster\n"));
  731                           335                 :              1 :     printf(_("  --sync-method=METHOD          set method for syncing files to disk\n"));
 3249 peter_e@gmx.net           336                 :              1 :     printf(_("  -?, --help                    show this help, then exit\n"));
                                337                 :              1 :     printf(_("\n"
                                338                 :                :              "Before running pg_upgrade you must:\n"
                                339                 :                :              "  create a new database cluster (using the new version of initdb)\n"
                                340                 :                :              "  shutdown the postmaster servicing the old cluster\n"
                                341                 :                :              "  shutdown the postmaster servicing the new cluster\n"));
                                342                 :              1 :     printf(_("\n"
                                343                 :                :              "When you run pg_upgrade, you must provide the following information:\n"
                                344                 :                :              "  the data directory for the old cluster  (-d DATADIR)\n"
                                345                 :                :              "  the data directory for the new cluster  (-D DATADIR)\n"
                                346                 :                :              "  the \"bin\" directory for the old version (-b BINDIR)\n"
                                347                 :                :              "  the \"bin\" directory for the new version (-B BINDIR)\n"));
                                348                 :              1 :     printf(_("\n"
                                349                 :                :              "For example:\n"
                                350                 :                :              "  pg_upgrade -d oldCluster/data -D newCluster/data -b oldCluster/bin -B newCluster/bin\n"
                                351                 :                :              "or\n"));
                                352                 :                : #ifndef WIN32
                                353                 :              1 :     printf(_("  $ export PGDATAOLD=oldCluster/data\n"
                                354                 :                :              "  $ export PGDATANEW=newCluster/data\n"
                                355                 :                :              "  $ export PGBINOLD=oldCluster/bin\n"
                                356                 :                :              "  $ export PGBINNEW=newCluster/bin\n"
                                357                 :                :              "  $ pg_upgrade\n"));
                                358                 :                : #else
                                359                 :                :     printf(_("  C:\\> set PGDATAOLD=oldCluster/data\n"
                                360                 :                :              "  C:\\> set PGDATANEW=newCluster/data\n"
                                361                 :                :              "  C:\\> set PGBINOLD=oldCluster/bin\n"
                                362                 :                :              "  C:\\> set PGBINNEW=newCluster/bin\n"
                                363                 :                :              "  C:\\> pg_upgrade\n"));
                                364                 :                : #endif
 2017 peter@eisentraut.org      365                 :              1 :     printf(_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
                                366                 :              1 :     printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
 5596 bruce@momjian.us          367                 :              1 : }
                                368                 :                : 
                                369                 :                : 
                                370                 :                : /*
                                371                 :                :  * check_required_directory()
                                372                 :                :  *
                                373                 :                :  * Checks a directory option.
                                374                 :                :  *  dirpath       - the directory name supplied on the command line, or NULL
                                375                 :                :  *  envVarName    - the name of an environment variable to get if dirpath is NULL
                                376                 :                :  *  useCwd        - true if OK to default to CWD
                                377                 :                :  *  cmdLineOption - the command line option for this directory
                                378                 :                :  *  description   - a description of this directory option
                                379                 :                :  *  missingOk     - true if OK that both dirpath and envVarName are not existing
                                380                 :                :  *
                                381                 :                :  * We use the last two arguments to construct a meaningful error message if the
                                382                 :                :  * user hasn't provided the required directory name.
                                383                 :                :  */
                                384                 :                : static void
 2471 tgl@sss.pgh.pa.us         385                 :             90 : check_required_directory(char **dirpath, const char *envVarName, bool useCwd,
                                386                 :                :                          const char *cmdLineOption, const char *description,
                                387                 :                :                          bool missingOk)
                                388                 :                : {
 5197 bruce@momjian.us          389   [ +  -  -  + ]:             90 :     if (*dirpath == NULL || strlen(*dirpath) == 0)
                                390                 :                :     {
                                391                 :                :         const char *envVar;
                                392                 :                : 
 5596 bruce@momjian.us          393   [ #  #  #  # ]:UIC           0 :         if ((envVar = getenv(envVarName)) && strlen(envVar))
 5436                           394                 :              0 :             *dirpath = pg_strdup(envVar);
 2471 tgl@sss.pgh.pa.us         395         [ #  # ]:              0 :         else if (useCwd)
                                396                 :                :         {
                                397                 :                :             char        cwd[MAXPGPATH];
                                398                 :                : 
                                399         [ #  # ]:              0 :             if (!getcwd(cwd, MAXPGPATH))
 1152                           400                 :              0 :                 pg_fatal("could not determine current directory");
 2471                           401                 :              0 :             *dirpath = pg_strdup(cwd);
                                402                 :                :         }
 2233 peter@eisentraut.org      403         [ #  # ]:              0 :         else if (missingOk)
                                404                 :              0 :             return;
                                405                 :                :         else
 4358 peter_e@gmx.net           406                 :              0 :             pg_fatal("You must identify the directory where the %s.\n"
                                407                 :                :                      "Please use the %s command-line option or the %s environment variable.",
                                408                 :                :                      description, cmdLineOption, envVarName);
                                409                 :                :     }
                                410                 :                : 
                                411                 :                :     /*
                                412                 :                :      * Clean up the path, in particular trimming any trailing path separators,
                                413                 :                :      * because we construct paths by appending to this path.
                                414                 :                :      */
 2471 tgl@sss.pgh.pa.us         415                 :GIC          90 :     canonicalize_path(*dirpath);
                                416                 :                : }
                                417                 :                : 
                                418                 :                : /*
                                419                 :                :  * adjust_data_dir
                                420                 :                :  *
                                421                 :                :  * If a configuration-only directory was specified, find the real data dir
                                422                 :                :  * by querying the running server.  This has limited checking because we
                                423                 :                :  * can't check for a running server because we can't find postmaster.pid.
                                424                 :                :  *
                                425                 :                :  * On entry, cluster->pgdata has been set from command line or env variable,
                                426                 :                :  * but cluster->pgconfig isn't set.  We fill both variables with corrected
                                427                 :                :  * values.
                                428                 :                :  */
                                429                 :                : void
 5083 bruce@momjian.us          430                 :             36 : adjust_data_dir(ClusterInfo *cluster)
                                431                 :                : {
                                432                 :                :     char        filename[MAXPGPATH];
                                433                 :                :     char        cmd[MAXPGPATH],
                                434                 :                :                 cmd_output[MAX_STRING];
                                435                 :                :     FILE       *fp,
                                436                 :                :                *output;
                                437                 :                :     int         rc;
                                438                 :                : 
                                439                 :                :     /* Initially assume config dir and data dir are the same */
 2471 tgl@sss.pgh.pa.us         440                 :             36 :     cluster->pgconfig = pg_strdup(cluster->pgdata);
                                441                 :                : 
                                442                 :                :     /* If there is no postgresql.conf, it can't be a config-only dir */
 5083 bruce@momjian.us          443                 :             36 :     snprintf(filename, sizeof(filename), "%s/postgresql.conf", cluster->pgconfig);
 4926                           444         [ -  + ]:             36 :     if ((fp = fopen(filename, "r")) == NULL)
 5083                           445                 :             36 :         return;
 4926                           446                 :             36 :     fclose(fp);
                                447                 :                : 
                                448                 :                :     /* If PG_VERSION exists, it can't be a config-only dir */
 5083                           449                 :             36 :     snprintf(filename, sizeof(filename), "%s/PG_VERSION", cluster->pgconfig);
 4926                           450         [ +  - ]:             36 :     if ((fp = fopen(filename, "r")) != NULL)
                                451                 :                :     {
                                452                 :             36 :         fclose(fp);
 5083                           453                 :             36 :         return;
                                454                 :                :     }
                                455                 :                : 
                                456                 :                :     /* Must be a configuration directory, so find the real data directory. */
                                457                 :                : 
 2976 alvherre@alvh.no-ip.      458         [ #  # ]:UIC           0 :     if (cluster == &old_cluster)
                                459                 :              0 :         prep_status("Finding the real data directory for the source cluster");
                                460                 :                :     else
                                461                 :              0 :         prep_status("Finding the real data directory for the target cluster");
                                462                 :                : 
                                463                 :                :     /*
                                464                 :                :      * We don't have a data directory yet, so we can't check the PG version,
                                465                 :                :      * so this might fail --- only works for PG 9.2+.   If this fails,
                                466                 :                :      * pg_upgrade will fail anyway because the data files will not be found.
                                467                 :                :      */
 3811 bruce@momjian.us          468                 :              0 :     snprintf(cmd, sizeof(cmd), "\"%s/postgres\" -D \"%s\" -C data_directory",
                                469                 :                :              cluster->bindir, cluster->pgconfig);
 1104 tgl@sss.pgh.pa.us         470                 :              0 :     fflush(NULL);
                                471                 :                : 
 5083 bruce@momjian.us          472   [ #  #  #  # ]:              0 :     if ((output = popen(cmd, "r")) == NULL ||
                                473                 :              0 :         fgets(cmd_output, sizeof(cmd_output), output) == NULL)
  543 michael@paquier.xyz       474                 :              0 :         pg_fatal("could not get data directory using %s: %m", cmd);
                                475                 :                : 
 1026 peter@eisentraut.org      476                 :              0 :     rc = pclose(output);
                                477         [ #  # ]:              0 :     if (rc != 0)
  855                           478                 :              0 :         pg_fatal("could not get data directory using %s: %s",
                                479                 :                :                  cmd, wait_result_to_str(rc));
                                480                 :                : 
                                481                 :                :     /* strip trailing newline and carriage return */
 2220 michael@paquier.xyz       482                 :              0 :     (void) pg_strip_crlf(cmd_output);
                                483                 :                : 
 5083 bruce@momjian.us          484                 :              0 :     cluster->pgdata = pg_strdup(cmd_output);
                                485                 :                : 
                                486                 :              0 :     check_ok();
                                487                 :                : }
                                488                 :                : 
                                489                 :                : 
                                490                 :                : /*
                                491                 :                :  * get_sock_dir
                                492                 :                :  *
                                493                 :                :  * Identify the socket directory to use for this cluster.  If we're doing
                                494                 :                :  * a live check (old cluster only), we need to find out where the postmaster
                                495                 :                :  * is listening.  Otherwise, we're going to put the socket into the current
                                496                 :                :  * directory.
                                497                 :                :  */
                                498                 :                : void
  407 nathan@postgresql.or      499                 :GIC          32 : get_sock_dir(ClusterInfo *cluster)
                                500                 :                : {
                                501                 :                : #if !defined(WIN32)
                                502   [ -  +  -  - ]:             32 :     if (!user_opts.live_check || cluster == &new_cluster)
 1360 tgl@sss.pgh.pa.us         503                 :             32 :         cluster->sockdir = user_opts.socketdir;
                                504                 :                :     else
                                505                 :                :     {
                                506                 :                :         /*
                                507                 :                :          * If we are doing a live check, we will use the old cluster's Unix
                                508                 :                :          * domain socket directory so we can connect to the live server.
                                509                 :                :          */
 1360 tgl@sss.pgh.pa.us         510                 :UIC           0 :         unsigned short orig_port = cluster->port;
                                511                 :                :         char        filename[MAXPGPATH],
                                512                 :                :                     line[MAXPGPATH];
                                513                 :                :         FILE       *fp;
                                514                 :                :         int         lineno;
                                515                 :                : 
                                516                 :              0 :         snprintf(filename, sizeof(filename), "%s/postmaster.pid",
                                517                 :                :                  cluster->pgdata);
                                518         [ #  # ]:              0 :         if ((fp = fopen(filename, "r")) == NULL)
  543 michael@paquier.xyz       519                 :              0 :             pg_fatal("could not open file \"%s\": %m", filename);
                                520                 :                : 
 1360 tgl@sss.pgh.pa.us         521                 :              0 :         for (lineno = 1;
                                522         [ #  # ]:              0 :              lineno <= Max(LOCK_FILE_LINE_PORT, LOCK_FILE_LINE_SOCKET_DIR);
                                523                 :              0 :              lineno++)
                                524                 :                :         {
                                525         [ #  # ]:              0 :             if (fgets(line, sizeof(line), fp) == NULL)
  543 michael@paquier.xyz       526                 :              0 :                 pg_fatal("could not read line %d from file \"%s\": %m",
                                527                 :                :                          lineno, filename);
                                528                 :                : 
                                529                 :                :             /* potentially overwrite user-supplied value */
 1360 tgl@sss.pgh.pa.us         530         [ #  # ]:              0 :             if (lineno == LOCK_FILE_LINE_PORT)
                                531                 :              0 :                 sscanf(line, "%hu", &old_cluster.port);
                                532         [ #  # ]:              0 :             if (lineno == LOCK_FILE_LINE_SOCKET_DIR)
                                533                 :                :             {
                                534                 :                :                 /* strip trailing newline and carriage return */
                                535                 :              0 :                 cluster->sockdir = pg_strdup(line);
                                536                 :              0 :                 (void) pg_strip_crlf(cluster->sockdir);
                                537                 :                :             }
                                538                 :                :         }
                                539                 :              0 :         fclose(fp);
                                540                 :                : 
                                541                 :                :         /* warn of port number correction */
                                542   [ #  #  #  # ]:              0 :         if (orig_port != DEF_PGUPORT && old_cluster.port != orig_port)
 1152                           543                 :              0 :             pg_log(PG_WARNING, "user-supplied old port number %hu corrected to %hu",
 1360                           544                 :              0 :                    orig_port, cluster->port);
                                545                 :                :     }
                                546                 :                : #else                           /* WIN32 */
                                547                 :                :     cluster->sockdir = NULL;
                                548                 :                : #endif
 4751 tgl@sss.pgh.pa.us         549                 :GIC          32 : }
        

Generated by: LCOV version 2.4-beta