Skip .DS_Store files in server side utils
authorDaniel Gustafsson
Tue, 13 Feb 2024 12:47:12 +0000 (13:47 +0100)
committerDaniel Gustafsson
Tue, 13 Feb 2024 12:47:12 +0000 (13:47 +0100)
The macOS Finder application creates .DS_Store files in directories
when opened,  which creates problems for serverside utilities which
expect all files to be PostgreSQL specific files.  Skip these files
when encountered in pg_checksums, pg_rewind and pg_basebackup.

This was extracted from a larger patchset for skipping hidden files
and system files, where the concencus was to just skip these. Since
this is equally likely to happen in every version, backpatch to all
supported versions.

Reported-by: Mark Guertin
Reviewed-by: Michael Paquier
Reviewed-by: Tobias Bussmann
Discussion: https://postgr.es/m/E258CE50-AB0E-455D-8AAD-BB4FE8F882FB@gmail.com
Backpatch-through: v12

doc/src/sgml/protocol.sgml
doc/src/sgml/ref/pg_basebackup.sgml
doc/src/sgml/ref/pg_rewind.sgml
src/backend/backup/basebackup.c
src/bin/pg_basebackup/t/010_pg_basebackup.pl
src/bin/pg_checksums/pg_checksums.c
src/bin/pg_checksums/t/002_actions.pl
src/bin/pg_rewind/filemap.c
src/bin/pg_rewind/t/003_extrafiles.pl

index b7ab0cdc697859471f68bd94fc54879e8f0e1203..c4ff7fcd034605e2fb1bccf0a0738b2de1e04c32 100644 (file)
@@ -3056,7 +3056,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;"
          
           Files other than regular files and directories, such as symbolic
           links (other than for the directories listed above) and special
-          device files, are skipped.  (Symbolic links
+          device and operating system files, are skipped.  (Symbolic links
           in pg_tblspc are maintained.)
          
         
index 79d3e657c32c245f9825c602d2760c0c3f49d9e1..c2fd27ca64b16b563b51dbcca6eca54e8a06f49d 100644 (file)
@@ -909,7 +909,8 @@ PostgreSQL documentation
    The backup will include all files in the data directory and tablespaces,
    including the configuration files and any additional files placed in the
    directory by third parties, except certain temporary files managed by
-   PostgreSQL.  But only regular files and directories are copied, except that
+   PostgreSQL and operating system files.  But only regular files and
+   directories are copied, except that
    symbolic links used for tablespaces are preserved.  Symbolic links pointing
    to certain directories known to PostgreSQL are copied as empty directories.
    Other symbolic links and special device files are skipped.
index 15cddd086b756b97f6d337622f118ecfeb050aa2..2de747ec37fced8622caf4eed4161e65a0e45737 100644 (file)
@@ -381,8 +381,9 @@ GRANT EXECUTE ON function pg_catalog.pg_read_binary_file(text, bigint, bigint, b
       backup_label,
       tablespace_map,
       pg_internal.init,
-      postmaster.opts, and
-      postmaster.pid, as well as any file or directory
+      postmaster.opts,
+      postmaster.pid and
+      .DS_Store as well as any file or directory
       beginning with pgsql_tmp, are omitted.
      
     
index 45be21131c5cb80c40c88fe8e208bad3550234f9..52f0cd3be190dec03341713a5a8c26b54501071b 100644 (file)
@@ -1202,6 +1202,10 @@ sendDir(bbsink *sink, const char *path, int basepathlen, bool sizeonly,
                    strlen(PG_TEMP_FILE_PREFIX)) == 0)
            continue;
 
+       /* Skip macOS system files */
+       if (strcmp(de->d_name, ".DS_Store") == 0)
+           continue;
+
        /*
         * Check if the postmaster has signaled us to exit, and abort with an
         * error in that case. The error handler further up will call
index b9f5e1266b424ec487d6ce968d45f978e3d15739..c8cef688d4982c7c5fa1523909869e8bee9eb138 100644 (file)
@@ -3,6 +3,7 @@
 
 use strict;
 use warnings;
+use Config;
 use File::Basename qw(basename dirname);
 use File::Path     qw(rmtree);
 use PostgreSQL::Test::Cluster;
@@ -179,6 +180,16 @@ foreach my $filename (
    close $file;
 }
 
+# Test that macOS system files are skipped. Only test on non-macOS systems
+# however since creating incorrect .DS_Store files on a macOS system may have
+# unintended side effects.
+if ($Config{osname} ne 'darwin')
+{
+   open my $file, '>>', "$pgdata/.DS_Store";
+   print $file "DONOTCOPY";
+   close $file;
+}
+
 # Connect to a database to create global/pg_internal.init.  If this is removed
 # the test to ensure global/pg_internal.init is not copied will return a false
 # positive.
@@ -248,6 +259,12 @@ foreach my $filename (
    ok(!-f "$tempdir/backup/$filename", "$filename not copied");
 }
 
+# We only test .DS_Store files being skipped on non-macOS systems
+if ($Config{osname} ne 'darwin')
+{
+   ok(!-f "$tempdir/backup/.DS_Store", ".DS_Store not copied");
+}
+
 # Unlogged relation forks other than init should not be copied
 ok(-f "$tempdir/backup/${baseUnloggedPath}_init",
    'unlogged init fork in backup');
index 19eb67e4854f7c1dbad01626a6e3cd0977a5e1ba..64b31d57d89caabe356ceac1ac5681d048bb85dc 100644 (file)
@@ -337,6 +337,10 @@ scan_directory(const char *basedir, const char *subdir, bool sizeonly)
                    strlen(PG_TEMP_FILES_DIR)) == 0)
            continue;
 
+       /* Skip macOS system files */
+       if (strcmp(de->d_name, ".DS_Store") == 0)
+           continue;
+
        snprintf(fn, sizeof(fn), "%s/%s", path, de->d_name);
        if (lstat(fn, &st) < 0)
            pg_fatal("could not stat file \"%s\": %m", fn);
index 2d63182d59f571181db00cfe2bd388d29061ec67..1d4d39db587be15af85a95bb9d766f93a990406f 100644 (file)
@@ -6,6 +6,7 @@
 
 use strict;
 use warnings;
+use Config;
 use PostgreSQL::Test::Cluster;
 use PostgreSQL::Test::Utils;
 
@@ -114,6 +115,12 @@ append_to_file "$pgdata/global/pgsql_tmp/1.1", "foo";
 append_to_file "$pgdata/global/pg_internal.init", "foo";
 append_to_file "$pgdata/global/pg_internal.init.123", "foo";
 
+# These are non-postgres macOS files, which should be ignored by the scan.
+# Only perform this test on non-macOS systems though as creating incorrect
+# system files may have side effects on macOS.
+append_to_file "$pgdata/global/.DS_Store", "foo"
+   unless ($Config{osname} eq 'darwin');
+
 # Enable checksums.
 command_ok([ 'pg_checksums', '--enable', '--no-sync', '-D', $pgdata ],
    "checksums successfully enabled in cluster");
index bd5c598e2008ee007dc1260b3d5cd21f41a48ca9..435742d20d1b5b86476829ef547db284a148b139 100644 (file)
@@ -647,6 +647,10 @@ decide_file_action(file_entry_t *entry)
    if (strcmp(path, "global/pg_control") == 0)
        return FILE_ACTION_NONE;
 
+   /* Skip macOS system files */
+   if (strstr(path, ".DS_Store") != NULL)
+       return FILE_ACTION_NONE;
+
    /*
     * Remove all files matching the exclusion filters in the target.
     */
index 2e06abb923777d3eb96efa46d18cb40b87110fdd..b6bfc5ed8087b1faa955dbd3fdc478440f3caec7 100644 (file)
@@ -5,6 +5,7 @@
 
 use strict;
 use warnings;
+use Config;
 use PostgreSQL::Test::Utils;
 use Test::More;
 
@@ -53,6 +54,10 @@ sub run_test
    append_to_file
      "$test_standby_datadir/tst_standby_dir/standby_subdir/standby_file4",
      "in standby4";
+   # Skip testing .DS_Store files on macOS to avoid risk of side effects
+   append_to_file
+     "$test_standby_datadir/tst_standby_dir/.DS_Store",
+     "macOS system file" unless ($Config{osname} eq 'darwin');
 
    mkdir "$test_primary_datadir/tst_primary_dir";
    append_to_file "$test_primary_datadir/tst_primary_dir/primary_file1",