LCOV - code coverage report
Current view: top level - src/bin/pg_upgrade - tablespace.c (source / functions) Hit Total Coverage
Test: PostgreSQL 13devel Lines: 23 39 59.0 %
Date: 2019-11-15 22:06:47 Functions: 3 3 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  *  tablespace.c
       3             :  *
       4             :  *  tablespace functions
       5             :  *
       6             :  *  Copyright (c) 2010-2019, PostgreSQL Global Development Group
       7             :  *  src/bin/pg_upgrade/tablespace.c
       8             :  */
       9             : 
      10             : #include "postgres_fe.h"
      11             : 
      12             : #include "pg_upgrade.h"
      13             : 
      14             : static void get_tablespace_paths(void);
      15             : static void set_tablespace_directory_suffix(ClusterInfo *cluster);
      16             : 
      17             : 
      18             : void
      19           2 : init_tablespaces(void)
      20             : {
      21           2 :     get_tablespace_paths();
      22             : 
      23           2 :     set_tablespace_directory_suffix(&old_cluster);
      24           2 :     set_tablespace_directory_suffix(&new_cluster);
      25             : 
      26           2 :     if (os_info.num_old_tablespaces > 0 &&
      27           0 :         strcmp(old_cluster.tablespace_suffix, new_cluster.tablespace_suffix) == 0)
      28           0 :         pg_fatal("Cannot upgrade to/from the same system catalog version when\n"
      29             :                  "using tablespaces.\n");
      30           2 : }
      31             : 
      32             : 
      33             : /*
      34             :  * get_tablespace_paths()
      35             :  *
      36             :  * Scans pg_tablespace and returns a malloc'ed array of all tablespace
      37             :  * paths. It's the caller's responsibility to free the array.
      38             :  */
      39             : static void
      40           2 : get_tablespace_paths(void)
      41             : {
      42           2 :     PGconn     *conn = connectToServer(&old_cluster, "template1");
      43             :     PGresult   *res;
      44             :     int         tblnum;
      45             :     int         i_spclocation;
      46             :     char        query[QUERY_ALLOC];
      47             : 
      48           2 :     snprintf(query, sizeof(query),
      49             :              "SELECT   %s "
      50             :              "FROM pg_catalog.pg_tablespace "
      51             :              "WHERE    spcname != 'pg_default' AND "
      52             :              "     spcname != 'pg_global'",
      53             :     /* 9.2 removed the spclocation column */
      54           2 :              (GET_MAJOR_VERSION(old_cluster.major_version) <= 901) ?
      55             :              "spclocation" : "pg_catalog.pg_tablespace_location(oid) AS spclocation");
      56             : 
      57           2 :     res = executeQueryOrDie(conn, "%s", query);
      58             : 
      59           2 :     if ((os_info.num_old_tablespaces = PQntuples(res)) != 0)
      60           0 :         os_info.old_tablespaces = (char **) pg_malloc(
      61           0 :                                                       os_info.num_old_tablespaces * sizeof(char *));
      62             :     else
      63           2 :         os_info.old_tablespaces = NULL;
      64             : 
      65           2 :     i_spclocation = PQfnumber(res, "spclocation");
      66             : 
      67           2 :     for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
      68             :     {
      69             :         struct stat statBuf;
      70             : 
      71           0 :         os_info.old_tablespaces[tblnum] = pg_strdup(
      72           0 :                                                     PQgetvalue(res, tblnum, i_spclocation));
      73             : 
      74             :         /*
      75             :          * Check that the tablespace path exists and is a directory.
      76             :          * Effectively, this is checking only for tables/indexes in
      77             :          * non-existent tablespace directories.  Databases located in
      78             :          * non-existent tablespaces already throw a backend error.
      79             :          * Non-existent tablespace directories can occur when a data directory
      80             :          * that contains user tablespaces is moved as part of pg_upgrade
      81             :          * preparation and the symbolic links are not updated.
      82             :          */
      83           0 :         if (stat(os_info.old_tablespaces[tblnum], &statBuf) != 0)
      84             :         {
      85           0 :             if (errno == ENOENT)
      86           0 :                 report_status(PG_FATAL,
      87             :                               "tablespace directory \"%s\" does not exist\n",
      88           0 :                               os_info.old_tablespaces[tblnum]);
      89             :             else
      90           0 :                 report_status(PG_FATAL,
      91             :                               "could not stat tablespace directory \"%s\": %s\n",
      92           0 :                               os_info.old_tablespaces[tblnum], strerror(errno));
      93             :         }
      94           0 :         if (!S_ISDIR(statBuf.st_mode))
      95           0 :             report_status(PG_FATAL,
      96             :                           "tablespace path \"%s\" is not a directory\n",
      97           0 :                           os_info.old_tablespaces[tblnum]);
      98             :     }
      99             : 
     100           2 :     PQclear(res);
     101             : 
     102           2 :     PQfinish(conn);
     103             : 
     104           2 :     return;
     105             : }
     106             : 
     107             : 
     108             : static void
     109           4 : set_tablespace_directory_suffix(ClusterInfo *cluster)
     110             : {
     111           4 :     if (GET_MAJOR_VERSION(cluster->major_version) <= 804)
     112           0 :         cluster->tablespace_suffix = pg_strdup("");
     113             :     else
     114             :     {
     115             :         /* This cluster has a version-specific subdirectory */
     116             : 
     117             :         /* The leading slash is needed to start a new directory. */
     118           8 :         cluster->tablespace_suffix = psprintf("/PG_%s_%d",
     119           4 :                                               cluster->major_version_str,
     120             :                                               cluster->controldata.cat_ver);
     121             :     }
     122           4 : }

Generated by: LCOV version 1.13