Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit8f15f74

Browse files
committed
Be more conservative about removing tablespace "symlinks".
Don't apply rmtree(), which will gleefully remove an entire subtree,and don't even apply unlink() unless it's symlink or a directory,the only things that we expect to find.Amit Kapila, with minor tweaks by me, per extensive discussionsinvolving Andrew Dunstan, Fujii Masao, and Heikki Linnakangas,at least some of whom also reviewed the code.
1 parentc66bc72 commit8f15f74

File tree

3 files changed

+69
-45
lines changed

3 files changed

+69
-45
lines changed

‎src/backend/access/transam/xlog.c

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include"catalog/catversion.h"
3939
#include"catalog/pg_control.h"
4040
#include"catalog/pg_database.h"
41+
#include"commands/tablespace.h"
4142
#include"miscadmin.h"
4243
#include"pgstat.h"
4344
#include"postmaster/bgwriter.h"
@@ -6074,7 +6075,6 @@ StartupXLOG(void)
60746075
if (read_tablespace_map(&tablespaces))
60756076
{
60766077
ListCell*lc;
6077-
structstatst;
60786078

60796079
foreach(lc,tablespaces)
60806080
{
@@ -6085,27 +6085,9 @@ StartupXLOG(void)
60856085

60866086
/*
60876087
* Remove the existing symlink if any and Create the symlink
6088-
* under PGDATA. We need to use rmtree instead of rmdir as
6089-
* the link location might contain directories or files
6090-
* corresponding to the actual path. Some tar utilities do
6091-
* things that way while extracting symlinks.
6088+
* under PGDATA.
60926089
*/
6093-
if (lstat(linkloc,&st)==0&&S_ISDIR(st.st_mode))
6094-
{
6095-
if (!rmtree(linkloc, true))
6096-
ereport(ERROR,
6097-
(errcode_for_file_access(),
6098-
errmsg("could not remove directory \"%s\": %m",
6099-
linkloc)));
6100-
}
6101-
else
6102-
{
6103-
if (unlink(linkloc)<0&&errno!=ENOENT)
6104-
ereport(ERROR,
6105-
(errcode_for_file_access(),
6106-
errmsg("could not remove symbolic link \"%s\": %m",
6107-
linkloc)));
6108-
}
6090+
remove_tablespace_symlink(linkloc);
61096091

61106092
if (symlink(ti->path,linkloc)<0)
61116093
ereport(ERROR,

‎src/backend/commands/tablespace.c

Lines changed: 65 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -627,31 +627,9 @@ create_tablespace_directories(const char *location, const Oid tablespaceoid)
627627

628628
/*
629629
* In recovery, remove old symlink, in case it points to the wrong place.
630-
*
631-
* On Windows, junction points act like directories so we must be able to
632-
* apply rmdir; in general it seems best to make this code work like the
633-
* symlink removal code in destroy_tablespace_directories, except that
634-
* failure to remove is always an ERROR.
635630
*/
636631
if (InRecovery)
637-
{
638-
if (lstat(linkloc,&st)==0&&S_ISDIR(st.st_mode))
639-
{
640-
if (rmdir(linkloc)<0)
641-
ereport(ERROR,
642-
(errcode_for_file_access(),
643-
errmsg("could not remove directory \"%s\": %m",
644-
linkloc)));
645-
}
646-
else
647-
{
648-
if (unlink(linkloc)<0&&errno!=ENOENT)
649-
ereport(ERROR,
650-
(errcode_for_file_access(),
651-
errmsg("could not remove symbolic link \"%s\": %m",
652-
linkloc)));
653-
}
654-
}
632+
remove_tablespace_symlink(linkloc);
655633

656634
/*
657635
* Create the symlink under PGDATA
@@ -802,7 +780,8 @@ destroy_tablespace_directories(Oid tablespaceoid, bool redo)
802780
errmsg("could not remove directory \"%s\": %m",
803781
linkloc)));
804782
}
805-
else
783+
#ifdefS_ISLNK
784+
elseif (S_ISLNK(st.st_mode))
806785
{
807786
if (unlink(linkloc)<0)
808787
{
@@ -814,6 +793,15 @@ destroy_tablespace_directories(Oid tablespaceoid, bool redo)
814793
linkloc)));
815794
}
816795
}
796+
#endif
797+
else
798+
{
799+
/* Refuse to remove anything that's not a directory or symlink */
800+
ereport(redo ?LOG :ERROR,
801+
(ERRCODE_SYSTEM_ERROR,
802+
errmsg("not a directory or symbolic link: \"%s\"",
803+
linkloc)));
804+
}
817805

818806
pfree(linkloc_with_version_dir);
819807
pfree(linkloc);
@@ -848,6 +836,59 @@ directory_is_empty(const char *path)
848836
return true;
849837
}
850838

839+
/*
840+
*remove_tablespace_symlink
841+
*
842+
* This function removes symlinks in pg_tblspc. On Windows, junction points
843+
* act like directories so we must be able to apply rmdir. This function
844+
* works like the symlink removal code in destroy_tablespace_directories,
845+
* except that failure to remove is always an ERROR. But if the file doesn't
846+
* exist at all, that's OK.
847+
*/
848+
void
849+
remove_tablespace_symlink(constchar*linkloc)
850+
{
851+
structstatst;
852+
853+
if (lstat(linkloc,&st)!=0)
854+
{
855+
if (errno==ENOENT)
856+
return;
857+
ereport(ERROR,
858+
(errcode_for_file_access(),
859+
errmsg("could not stat \"%s\": %m",linkloc)));
860+
}
861+
862+
if (S_ISDIR(st.st_mode))
863+
{
864+
/*
865+
* This will fail if the directory isn't empty, but not
866+
* if it's a junction point.
867+
*/
868+
if (rmdir(linkloc)<0)
869+
ereport(ERROR,
870+
(errcode_for_file_access(),
871+
errmsg("could not remove directory \"%s\": %m",
872+
linkloc)));
873+
}
874+
#ifdefS_ISLNK
875+
elseif (S_ISLNK(st.st_mode))
876+
{
877+
if (unlink(linkloc)<0&&errno!=ENOENT)
878+
ereport(ERROR,
879+
(errcode_for_file_access(),
880+
errmsg("could not remove symbolic link \"%s\": %m",
881+
linkloc)));
882+
}
883+
#endif
884+
else
885+
{
886+
/* Refuse to remove anything that's not a directory or symlink */
887+
ereport(ERROR,
888+
(errmsg("not a directory or symbolic link: \"%s\"",
889+
linkloc)));
890+
}
891+
}
851892

852893
/*
853894
* Rename a tablespace

‎src/include/commands/tablespace.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ extern Oidget_tablespace_oid(const char *tablespacename, bool missing_ok);
5656
externchar*get_tablespace_name(Oidspc_oid);
5757

5858
externbooldirectory_is_empty(constchar*path);
59+
externvoidremove_tablespace_symlink(constchar*linkloc);
5960

6061
externvoidtblspc_redo(XLogReaderState*rptr);
6162
externvoidtblspc_desc(StringInfobuf,XLogReaderState*rptr);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp