LCOV - differential code coverage report
Current view: top level - src/bin/pg_upgrade - file.c (source / functions) Coverage Total Hit UNC UBC GNC CBC DUB
Current: Differential Code Coverage 16@8cea358b128 vs 17@8cea358b128 Lines: 10.8 % 139 15 42 82 15 32
Current Date: 2024-04-14 14:21:10 Functions: 12.5 % 8 1 7 1
Baseline: 16@8cea358b128 Branches: 7.9 % 76 6 14 56 6
Baseline Date: 2024-04-14 14:21:09 Line coverage date bins:
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed [..60] days: 0.0 % 42 0 42
(240..) days: 15.5 % 97 15 82 15
Function coverage date bins:
[..60] days: 0.0 % 2 0 2
(240..) days: 16.7 % 6 1 5 1
Branch coverage date bins:
[..60] days: 0.0 % 14 0 14
(240..) days: 9.7 % 62 6 56 6

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*
                                  2                 :                :  *  file.c
                                  3                 :                :  *
                                  4                 :                :  *  file system operations
                                  5                 :                :  *
                                  6                 :                :  *  Copyright (c) 2010-2024, PostgreSQL Global Development Group
                                  7                 :                :  *  src/bin/pg_upgrade/file.c
                                  8                 :                :  */
                                  9                 :                : 
                                 10                 :                : #include "postgres_fe.h"
                                 11                 :                : 
                                 12                 :                : #include <sys/stat.h>
                                 13                 :                : #include <limits.h>
                                 14                 :                : #include <fcntl.h>
                                 15                 :                : #ifdef HAVE_COPYFILE_H
                                 16                 :                : #include <copyfile.h>
                                 17                 :                : #endif
                                 18                 :                : #ifdef __linux__
                                 19                 :                : #include <sys/ioctl.h>
                                 20                 :                : #include <linux/fs.h>
                                 21                 :                : #endif
                                 22                 :                : 
                                 23                 :                : #include "access/visibilitymapdefs.h"
                                 24                 :                : #include "common/file_perm.h"
                                 25                 :                : #include "pg_upgrade.h"
                                 26                 :                : #include "storage/bufpage.h"
                                 27                 :                : #include "storage/checksum.h"
                                 28                 :                : #include "storage/checksum_impl.h"
                                 29                 :                : 
                                 30                 :                : 
                                 31                 :                : /*
                                 32                 :                :  * cloneFile()
                                 33                 :                :  *
                                 34                 :                :  * Clones/reflinks a relation file from src to dst.
                                 35                 :                :  *
                                 36                 :                :  * schemaName/relName are relation's SQL name (used for error messages only).
                                 37                 :                :  */
                                 38                 :                : void
 1985 peter_e@gmx.net            39                 :UBC           0 : cloneFile(const char *src, const char *dst,
                                 40                 :                :           const char *schemaName, const char *relName)
                                 41                 :                : {
                                 42                 :                : #if defined(HAVE_COPYFILE) && defined(COPYFILE_CLONE_FORCE)
                                 43                 :                :     if (copyfile(src, dst, NULL, COPYFILE_CLONE_FORCE) < 0)
                                 44                 :                :         pg_fatal("error while cloning relation \"%s.%s\" (\"%s\" to \"%s\"): %m",
                                 45                 :                :                  schemaName, relName, src, dst);
                                 46                 :                : #elif defined(__linux__) && defined(FICLONE)
                                 47                 :                :     int         src_fd;
                                 48                 :                :     int         dest_fd;
                                 49                 :                : 
                                 50         [ #  # ]:              0 :     if ((src_fd = open(src, O_RDONLY | PG_BINARY, 0)) < 0)
   33 michael@paquier.xyz        51                 :UNC           0 :         pg_fatal("error while cloning relation \"%s.%s\": could not open file \"%s\": %m",
                                 52                 :                :                  schemaName, relName, src);
                                 53                 :                : 
 1985 peter_e@gmx.net            54         [ #  # ]:UBC           0 :     if ((dest_fd = open(dst, O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
                                 55                 :                :                         pg_file_create_mode)) < 0)
   33 michael@paquier.xyz        56                 :UNC           0 :         pg_fatal("error while cloning relation \"%s.%s\": could not create file \"%s\": %m",
                                 57                 :                :                  schemaName, relName, dst);
                                 58                 :                : 
 1985 peter_e@gmx.net            59         [ #  # ]:UBC           0 :     if (ioctl(dest_fd, FICLONE, src_fd) < 0)
                                 60                 :                :     {
  622 michael@paquier.xyz        61                 :              0 :         int         save_errno = errno;
                                 62                 :                : 
 1985 peter_e@gmx.net            63                 :              0 :         unlink(dst);
                                 64                 :                : 
  642 tgl@sss.pgh.pa.us          65                 :              0 :         pg_fatal("error while cloning relation \"%s.%s\" (\"%s\" to \"%s\"): %s",
                                 66                 :                :                  schemaName, relName, src, dst, strerror(save_errno));
                                 67                 :                :     }
                                 68                 :                : 
 1985 peter_e@gmx.net            69                 :              0 :     close(src_fd);
                                 70                 :              0 :     close(dest_fd);
                                 71                 :                : #endif
                                 72                 :              0 : }
                                 73                 :                : 
                                 74                 :                : 
                                 75                 :                : /*
                                 76                 :                :  * copyFile()
                                 77                 :                :  *
                                 78                 :                :  * Copies a relation file from src to dst.
                                 79                 :                :  * schemaName/relName are relation's SQL name (used for error messages only).
                                 80                 :                :  */
                                 81                 :                : void
 2753 tgl@sss.pgh.pa.us          82                 :CBC        1674 : copyFile(const char *src, const char *dst,
                                 83                 :                :          const char *schemaName, const char *relName)
                                 84                 :                : {
                                 85                 :                : #ifndef WIN32
                                 86                 :                :     int         src_fd;
                                 87                 :                :     int         dest_fd;
                                 88                 :                :     char       *buffer;
                                 89                 :                : 
                                 90         [ -  + ]:           1674 :     if ((src_fd = open(src, O_RDONLY | PG_BINARY, 0)) < 0)
   33 michael@paquier.xyz        91                 :UNC           0 :         pg_fatal("error while copying relation \"%s.%s\": could not open file \"%s\": %m",
                                 92                 :                :                  schemaName, relName, src);
                                 93                 :                : 
 2753 tgl@sss.pgh.pa.us          94         [ -  + ]:CBC        1674 :     if ((dest_fd = open(dst, O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
                                 95                 :                :                         pg_file_create_mode)) < 0)
   33 michael@paquier.xyz        96                 :UNC           0 :         pg_fatal("error while copying relation \"%s.%s\": could not create file \"%s\": %m",
                                 97                 :                :                  schemaName, relName, dst);
                                 98                 :                : 
                                 99                 :                :     /* copy in fairly large chunks for best efficiency */
                                100                 :                : #define COPY_BUF_SIZE (50 * BLCKSZ)
                                101                 :                : 
 4159 bruce@momjian.us          102                 :CBC        1674 :     buffer = (char *) pg_malloc(COPY_BUF_SIZE);
                                103                 :                : 
                                104                 :                :     /* perform data copying i.e read src source, write to destination */
                                105                 :                :     while (true)
 5086                           106                 :           1354 :     {
                                107                 :           3028 :         ssize_t     nbytes = read(src_fd, buffer, COPY_BUF_SIZE);
                                108                 :                : 
                                109         [ -  + ]:           3028 :         if (nbytes < 0)
   33 michael@paquier.xyz       110                 :UNC           0 :             pg_fatal("error while copying relation \"%s.%s\": could not read file \"%s\": %m",
                                111                 :                :                      schemaName, relName, src);
                                112                 :                : 
 5086 bruce@momjian.us          113         [ +  + ]:CBC        3028 :         if (nbytes == 0)
                                114                 :           1674 :             break;
                                115                 :                : 
                                116                 :           1354 :         errno = 0;
                                117         [ -  + ]:           1354 :         if (write(dest_fd, buffer, nbytes) != nbytes)
                                118                 :                :         {
                                119                 :                :             /* if write didn't set errno, assume problem is no disk space */
 3800 peter_e@gmx.net           120         [ #  # ]:UBC           0 :             if (errno == 0)
                                121                 :              0 :                 errno = ENOSPC;
   33 michael@paquier.xyz       122                 :UNC           0 :             pg_fatal("error while copying relation \"%s.%s\": could not write file \"%s\": %m",
                                123                 :                :                      schemaName, relName, dst);
                                124                 :                :         }
                                125                 :                :     }
                                126                 :                : 
 4159 bruce@momjian.us          127                 :CBC        1674 :     pg_free(buffer);
 2753 tgl@sss.pgh.pa.us         128                 :           1674 :     close(src_fd);
                                129                 :           1674 :     close(dest_fd);
                                130                 :                : 
                                131                 :                : #else                           /* WIN32 */
                                132                 :                : 
                                133                 :                :     if (CopyFile(src, dst, true) == 0)
                                134                 :                :     {
                                135                 :                :         _dosmaperr(GetLastError());
                                136                 :                :         pg_fatal("error while copying relation \"%s.%s\" (\"%s\" to \"%s\"): %m",
                                137                 :                :                  schemaName, relName, src, dst);
                                138                 :                :     }
                                139                 :                : 
                                140                 :                : #endif                          /* WIN32 */
                                141                 :           1674 : }
                                142                 :                : 
                                143                 :                : 
                                144                 :                : /*
                                145                 :                :  * copyFileByRange()
                                146                 :                :  *
                                147                 :                :  * Copies a relation file from src to dst.
                                148                 :                :  * schemaName/relName are relation's SQL name (used for error messages only).
                                149                 :                :  */
                                150                 :                : void
   39 tmunro@postgresql.or      151                 :UNC           0 : copyFileByRange(const char *src, const char *dst,
                                152                 :                :                 const char *schemaName, const char *relName)
                                153                 :                : {
                                154                 :                : #ifdef HAVE_COPY_FILE_RANGE
                                155                 :                :     int         src_fd;
                                156                 :                :     int         dest_fd;
                                157                 :                :     ssize_t     nbytes;
                                158                 :                : 
                                159         [ #  # ]:              0 :     if ((src_fd = open(src, O_RDONLY | PG_BINARY, 0)) < 0)
   33 michael@paquier.xyz       160                 :              0 :         pg_fatal("error while copying relation \"%s.%s\": could not open file \"%s\": %m",
                                161                 :                :                  schemaName, relName, src);
                                162                 :                : 
   39 tmunro@postgresql.or      163         [ #  # ]:              0 :     if ((dest_fd = open(dst, O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
                                164                 :                :                         pg_file_create_mode)) < 0)
   33 michael@paquier.xyz       165                 :              0 :         pg_fatal("error while copying relation \"%s.%s\": could not create file \"%s\": %m",
                                166                 :                :                  schemaName, relName, dst);
                                167                 :                : 
                                168                 :                :     do
                                169                 :                :     {
   39 tmunro@postgresql.or      170                 :              0 :         nbytes = copy_file_range(src_fd, NULL, dest_fd, NULL, SSIZE_MAX, 0);
                                171         [ #  # ]:              0 :         if (nbytes < 0)
   33 michael@paquier.xyz       172                 :              0 :             pg_fatal("error while copying relation \"%s.%s\": could not copy file range from \"%s\" to \"%s\": %m",
                                173                 :                :                      schemaName, relName, src, dst);
                                174                 :                :     }
   39 tmunro@postgresql.or      175         [ #  # ]:              0 :     while (nbytes > 0);
                                176                 :                : 
                                177                 :              0 :     close(src_fd);
                                178                 :              0 :     close(dest_fd);
                                179                 :                : #endif
                                180                 :              0 : }
                                181                 :                : 
                                182                 :                : 
                                183                 :                : /*
                                184                 :                :  * linkFile()
                                185                 :                :  *
                                186                 :                :  * Hard-links a relation file from src to dst.
                                187                 :                :  * schemaName/relName are relation's SQL name (used for error messages only).
                                188                 :                :  */
                                189                 :                : void
 2753 tgl@sss.pgh.pa.us         190                 :UBC           0 : linkFile(const char *src, const char *dst,
                                191                 :                :          const char *schemaName, const char *relName)
                                192                 :                : {
 1502 peter@eisentraut.org      193         [ #  # ]:              0 :     if (link(src, dst) < 0)
   33 michael@paquier.xyz       194                 :UNC           0 :         pg_fatal("error while creating link for relation \"%s.%s\" (\"%s\" to \"%s\"): %m",
                                195                 :                :                  schemaName, relName, src, dst);
 5086 bruce@momjian.us          196                 :UBC           0 : }
                                197                 :                : 
                                198                 :                : 
                                199                 :                : /*
                                200                 :                :  * rewriteVisibilityMap()
                                201                 :                :  *
                                202                 :                :  * Transform a visibility map file, copying from src to dst.
                                203                 :                :  * schemaName/relName are relation's SQL name (used for error messages only).
                                204                 :                :  *
                                205                 :                :  * In versions of PostgreSQL prior to catversion 201603011, PostgreSQL's
                                206                 :                :  * visibility map included one bit per heap page; it now includes two.
                                207                 :                :  * When upgrading a cluster from before that time to a current PostgreSQL
                                208                 :                :  * version, we could refuse to copy visibility maps from the old cluster
                                209                 :                :  * to the new cluster; the next VACUUM would recreate them, but at the
                                210                 :                :  * price of scanning the entire table.  So, instead, we rewrite the old
                                211                 :                :  * visibility maps in the new format.  That way, the all-visible bits
                                212                 :                :  * remain set for the pages for which they were set previously.  The
                                213                 :                :  * all-frozen bits are never set by this conversion; we leave that to VACUUM.
                                214                 :                :  */
                                215                 :                : void
 2753 tgl@sss.pgh.pa.us         216                 :              0 : rewriteVisibilityMap(const char *fromfile, const char *tofile,
                                217                 :                :                      const char *schemaName, const char *relName)
                                218                 :                : {
                                219                 :                :     int         src_fd;
                                220                 :                :     int         dst_fd;
                                221                 :                :     PGIOAlignedBlock buffer;
                                222                 :                :     PGIOAlignedBlock new_vmbuf;
 2869 rhaas@postgresql.org      223                 :              0 :     ssize_t     totalBytesRead = 0;
                                224                 :                :     ssize_t     src_filesize;
                                225                 :                :     int         rewriteVmBytesPerPage;
 2956                           226                 :              0 :     BlockNumber new_blkno = 0;
                                227                 :                :     struct stat statbuf;
                                228                 :                : 
                                229                 :                :     /* Compute number of old-format bytes per new page */
                                230                 :              0 :     rewriteVmBytesPerPage = (BLCKSZ - SizeOfPageHeaderData) / 2;
                                231                 :                : 
 2753 tgl@sss.pgh.pa.us         232         [ #  # ]:              0 :     if ((src_fd = open(fromfile, O_RDONLY | PG_BINARY, 0)) < 0)
   33 michael@paquier.xyz       233                 :UNC           0 :         pg_fatal("error while copying relation \"%s.%s\": could not open file \"%s\": %m",
                                234                 :                :                  schemaName, relName, fromfile);
                                235                 :                : 
 2956 rhaas@postgresql.org      236         [ #  # ]:UBC           0 :     if (fstat(src_fd, &statbuf) != 0)
   33 michael@paquier.xyz       237                 :UNC           0 :         pg_fatal("error while copying relation \"%s.%s\": could not stat file \"%s\": %m",
                                238                 :                :                  schemaName, relName, fromfile);
                                239                 :                : 
 2753 tgl@sss.pgh.pa.us         240         [ #  # ]:UBC           0 :     if ((dst_fd = open(tofile, O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
                                241                 :                :                        pg_file_create_mode)) < 0)
   33 michael@paquier.xyz       242                 :UNC           0 :         pg_fatal("error while copying relation \"%s.%s\": could not create file \"%s\": %m",
                                243                 :                :                  schemaName, relName, tofile);
                                244                 :                : 
                                245                 :                :     /* Save old file size */
 2956 rhaas@postgresql.org      246                 :UBC           0 :     src_filesize = statbuf.st_size;
                                247                 :                : 
                                248                 :                :     /*
                                249                 :                :      * Turn each visibility map page into 2 pages one by one. Each new page
                                250                 :                :      * has the same page header as the old one.  If the last section of the
                                251                 :                :      * last page is empty, we skip it, mostly to avoid turning one-page
                                252                 :                :      * visibility maps for small relations into two pages needlessly.
                                253                 :                :      */
 2869                           254         [ #  # ]:              0 :     while (totalBytesRead < src_filesize)
                                255                 :                :     {
                                256                 :                :         ssize_t     bytesRead;
                                257                 :                :         char       *old_cur;
                                258                 :                :         char       *old_break;
                                259                 :                :         char       *old_blkend;
                                260                 :                :         PageHeaderData pageheader;
                                261                 :                :         bool        old_lastblk;
                                262                 :                : 
 2052 tgl@sss.pgh.pa.us         263         [ #  # ]:              0 :         if ((bytesRead = read(src_fd, buffer.data, BLCKSZ)) != BLCKSZ)
                                264                 :                :         {
 2753                           265         [ #  # ]:              0 :             if (bytesRead < 0)
   33 michael@paquier.xyz       266                 :UNC           0 :                 pg_fatal("error while copying relation \"%s.%s\": could not read file \"%s\": %m",
                                267                 :                :                          schemaName, relName, fromfile);
                                268                 :                :             else
  642 tgl@sss.pgh.pa.us         269                 :UBC           0 :                 pg_fatal("error while copying relation \"%s.%s\": partial page found in file \"%s\"",
                                270                 :                :                          schemaName, relName, fromfile);
                                271                 :                :         }
                                272                 :                : 
 2869 rhaas@postgresql.org      273                 :              0 :         totalBytesRead += BLCKSZ;
                                274                 :              0 :         old_lastblk = (totalBytesRead == src_filesize);
                                275                 :                : 
                                276                 :                :         /* Save the page header data */
 2052 tgl@sss.pgh.pa.us         277                 :              0 :         memcpy(&pageheader, buffer.data, SizeOfPageHeaderData);
                                278                 :                : 
                                279                 :                :         /*
                                280                 :                :          * These old_* variables point to old visibility map page. old_cur
                                281                 :                :          * points to current position on old page. old_blkend points to end of
                                282                 :                :          * old block.  old_break is the end+1 position on the old page for the
                                283                 :                :          * data that will be transferred to the current new page.
                                284                 :                :          */
                                285                 :              0 :         old_cur = buffer.data + SizeOfPageHeaderData;
                                286                 :              0 :         old_blkend = buffer.data + bytesRead;
 2956 rhaas@postgresql.org      287                 :              0 :         old_break = old_cur + rewriteVmBytesPerPage;
                                288                 :                : 
 2753 tgl@sss.pgh.pa.us         289         [ #  # ]:              0 :         while (old_break <= old_blkend)
                                290                 :                :         {
                                291                 :                :             char       *new_cur;
 2956 rhaas@postgresql.org      292                 :              0 :             bool        empty = true;
                                293                 :                :             bool        old_lastpart;
                                294                 :                : 
                                295                 :                :             /* First, copy old page header to new page */
 2052 tgl@sss.pgh.pa.us         296                 :              0 :             memcpy(new_vmbuf.data, &pageheader, SizeOfPageHeaderData);
                                297                 :                : 
                                298                 :                :             /* Rewriting the last part of the last old page? */
 2753                           299   [ #  #  #  # ]:              0 :             old_lastpart = old_lastblk && (old_break == old_blkend);
                                300                 :                : 
 2052                           301                 :              0 :             new_cur = new_vmbuf.data + SizeOfPageHeaderData;
                                302                 :                : 
                                303                 :                :             /* Process old page bytes one by one, and turn it into new page. */
 2753                           304         [ #  # ]:              0 :             while (old_cur < old_break)
                                305                 :                :             {
                                306                 :              0 :                 uint8       byte = *(uint8 *) old_cur;
 2956 rhaas@postgresql.org      307                 :              0 :                 uint16      new_vmbits = 0;
                                308                 :                :                 int         i;
                                309                 :                : 
                                310                 :                :                 /* Generate new format bits while keeping old information */
                                311         [ #  # ]:              0 :                 for (i = 0; i < BITS_PER_BYTE; i++)
                                312                 :                :                 {
 2753 tgl@sss.pgh.pa.us         313         [ #  # ]:              0 :                     if (byte & (1 << i))
                                314                 :                :                     {
 2956 rhaas@postgresql.org      315                 :              0 :                         empty = false;
 2753 tgl@sss.pgh.pa.us         316                 :              0 :                         new_vmbits |=
                                317                 :              0 :                             VISIBILITYMAP_ALL_VISIBLE << (BITS_PER_HEAPBLOCK * i);
                                318                 :                :                     }
                                319                 :                :                 }
                                320                 :                : 
                                321                 :                :                 /* Copy new visibility map bytes to new-format page */
                                322                 :              0 :                 new_cur[0] = (char) (new_vmbits & 0xFF);
                                323                 :              0 :                 new_cur[1] = (char) (new_vmbits >> 8);
                                324                 :                : 
                                325                 :              0 :                 old_cur++;
 2956 rhaas@postgresql.org      326                 :              0 :                 new_cur += BITS_PER_HEAPBLOCK;
                                327                 :                :             }
                                328                 :                : 
                                329                 :                :             /* If the last part of the last page is empty, skip writing it */
                                330   [ #  #  #  # ]:              0 :             if (old_lastpart && empty)
                                331                 :              0 :                 break;
                                332                 :                : 
                                333                 :                :             /* Set new checksum for visibility map page, if enabled */
 2753 tgl@sss.pgh.pa.us         334         [ #  # ]:              0 :             if (new_cluster.controldata.data_checksum_version != 0)
 2052                           335                 :              0 :                 ((PageHeader) new_vmbuf.data)->pd_checksum =
                                336                 :              0 :                     pg_checksum_page(new_vmbuf.data, new_blkno);
                                337                 :                : 
 2753                           338                 :              0 :             errno = 0;
 2052                           339         [ #  # ]:              0 :             if (write(dst_fd, new_vmbuf.data, BLCKSZ) != BLCKSZ)
                                340                 :                :             {
                                341                 :                :                 /* if write didn't set errno, assume problem is no disk space */
 2753                           342         [ #  # ]:              0 :                 if (errno == 0)
                                343                 :              0 :                     errno = ENOSPC;
   33 michael@paquier.xyz       344                 :UNC           0 :                 pg_fatal("error while copying relation \"%s.%s\": could not write file \"%s\": %m",
                                345                 :                :                          schemaName, relName, tofile);
                                346                 :                :             }
                                347                 :                : 
                                348                 :                :             /* Advance for next new page */
 2956 rhaas@postgresql.org      349                 :UBC           0 :             old_break += rewriteVmBytesPerPage;
                                350                 :              0 :             new_blkno++;
                                351                 :                :         }
                                352                 :                :     }
                                353                 :                : 
                                354                 :                :     /* Clean up */
                                355                 :              0 :     close(dst_fd);
                                356                 :              0 :     close(src_fd);
                                357                 :              0 : }
                                358                 :                : 
                                359                 :                : void
 1985 peter_e@gmx.net           360                 :              0 : check_file_clone(void)
                                361                 :                : {
                                362                 :                :     char        existing_file[MAXPGPATH];
                                363                 :                :     char        new_link_file[MAXPGPATH];
                                364                 :                : 
                                365                 :              0 :     snprintf(existing_file, sizeof(existing_file), "%s/PG_VERSION", old_cluster.pgdata);
                                366                 :              0 :     snprintf(new_link_file, sizeof(new_link_file), "%s/PG_VERSION.clonetest", new_cluster.pgdata);
                                367                 :              0 :     unlink(new_link_file);      /* might fail */
                                368                 :                : 
                                369                 :                : #if defined(HAVE_COPYFILE) && defined(COPYFILE_CLONE_FORCE)
                                370                 :                :     if (copyfile(existing_file, new_link_file, NULL, COPYFILE_CLONE_FORCE) < 0)
                                371                 :                :         pg_fatal("could not clone file between old and new data directories: %m");
                                372                 :                : #elif defined(__linux__) && defined(FICLONE)
                                373                 :                :     {
                                374                 :                :         int         src_fd;
                                375                 :                :         int         dest_fd;
                                376                 :                : 
                                377         [ #  # ]:              0 :         if ((src_fd = open(existing_file, O_RDONLY | PG_BINARY, 0)) < 0)
   33 michael@paquier.xyz       378                 :UNC           0 :             pg_fatal("could not open file \"%s\": %m",
                                379                 :                :                      existing_file);
                                380                 :                : 
 1985 peter_e@gmx.net           381         [ #  # ]:UBC           0 :         if ((dest_fd = open(new_link_file, O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
                                382                 :                :                             pg_file_create_mode)) < 0)
   33 michael@paquier.xyz       383                 :UNC           0 :             pg_fatal("could not create file \"%s\": %m",
                                384                 :                :                      new_link_file);
                                385                 :                : 
 1985 peter_e@gmx.net           386         [ #  # ]:UBC           0 :         if (ioctl(dest_fd, FICLONE, src_fd) < 0)
   33 michael@paquier.xyz       387                 :UNC           0 :             pg_fatal("could not clone file between old and new data directories: %m");
                                388                 :                : 
 1985 peter_e@gmx.net           389                 :UBC           0 :         close(src_fd);
                                390                 :              0 :         close(dest_fd);
                                391                 :                :     }
                                392                 :                : #else
                                393                 :                :     pg_fatal("file cloning not supported on this platform");
                                394                 :                : #endif
                                395                 :                : 
                                396                 :              0 :     unlink(new_link_file);
                                397                 :              0 : }
                                398                 :                : 
                                399                 :                : void
   39 tmunro@postgresql.or      400                 :UNC           0 : check_copy_file_range(void)
                                401                 :                : {
                                402                 :                :     char        existing_file[MAXPGPATH];
                                403                 :                :     char        new_link_file[MAXPGPATH];
                                404                 :                : 
                                405                 :              0 :     snprintf(existing_file, sizeof(existing_file), "%s/PG_VERSION", old_cluster.pgdata);
                                406                 :              0 :     snprintf(new_link_file, sizeof(new_link_file), "%s/PG_VERSION.copy_file_range_test", new_cluster.pgdata);
                                407                 :              0 :     unlink(new_link_file);      /* might fail */
                                408                 :                : 
                                409                 :                : #if defined(HAVE_COPY_FILE_RANGE)
                                410                 :                :     {
                                411                 :                :         int         src_fd;
                                412                 :                :         int         dest_fd;
                                413                 :                : 
                                414         [ #  # ]:              0 :         if ((src_fd = open(existing_file, O_RDONLY | PG_BINARY, 0)) < 0)
   33 michael@paquier.xyz       415                 :              0 :             pg_fatal("could not open file \"%s\": %m",
                                416                 :                :                      existing_file);
                                417                 :                : 
   39 tmunro@postgresql.or      418         [ #  # ]:              0 :         if ((dest_fd = open(new_link_file, O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
                                419                 :                :                             pg_file_create_mode)) < 0)
   33 michael@paquier.xyz       420                 :              0 :             pg_fatal("could not create file \"%s\": %m",
                                421                 :                :                      new_link_file);
                                422                 :                : 
   39 tmunro@postgresql.or      423         [ #  # ]:              0 :         if (copy_file_range(src_fd, NULL, dest_fd, NULL, SSIZE_MAX, 0) < 0)
   33 michael@paquier.xyz       424                 :              0 :             pg_fatal("could not copy file range between old and new data directories: %m");
                                425                 :                : 
   39 tmunro@postgresql.or      426                 :              0 :         close(src_fd);
                                427                 :              0 :         close(dest_fd);
                                428                 :                :     }
                                429                 :                : #else
                                430                 :                :     pg_fatal("copy_file_range not supported on this platform");
                                431                 :                : #endif
                                432                 :                : 
                                433                 :              0 :     unlink(new_link_file);
                                434                 :              0 : }
                                435                 :                : 
                                436                 :                : void
 4926 bruce@momjian.us          437                 :UBC           0 : check_hard_link(void)
                                438                 :                : {
                                439                 :                :     char        existing_file[MAXPGPATH];
                                440                 :                :     char        new_link_file[MAXPGPATH];
                                441                 :                : 
                                442                 :              0 :     snprintf(existing_file, sizeof(existing_file), "%s/PG_VERSION", old_cluster.pgdata);
                                443                 :              0 :     snprintf(new_link_file, sizeof(new_link_file), "%s/PG_VERSION.linktest", new_cluster.pgdata);
 5086                           444                 :              0 :     unlink(new_link_file);      /* might fail */
                                445                 :                : 
 1502 peter@eisentraut.org      446         [ #  # ]:              0 :     if (link(existing_file, new_link_file) < 0)
   33 michael@paquier.xyz       447                 :UNC           0 :         pg_fatal("could not create hard link between old and new data directories: %m\n"
                                448                 :                :                  "In link mode the old and new data directories must be on the same file system.");
                                449                 :                : 
 5086 bruce@momjian.us          450                 :UBC           0 :     unlink(new_link_file);
                                451                 :              0 : }
        

Generated by: LCOV version 2.1-beta2-3-g6141622