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

Commitb659ab0

Browse files
committed
Create an fd.c entry point that is just like plain open(2) except that
it will close VFDs if necessary to surmount ENFILE or EMFILE failures.Make use of this in md.c, xlog.c, and user.c routines that wereformerly vulnerable to these failures. In particular, this shouldhandle failures of mdblindwrt() that have been observed under heavyload conditions. (By golly, every other process on the system maycrash after Postgres eats up all the kernel FDs, but Postgres willkeep going!)
1 parent60b941f commitb659ab0

File tree

5 files changed

+72
-99
lines changed

5 files changed

+72
-99
lines changed

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

Lines changed: 12 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
9-
* $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.13 2000/04/12 17:14:53 momjian Exp $
9+
* $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.14 2000/06/02 03:58:34 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -44,8 +44,6 @@ boolStopIfError = false;
4444
SPINLOCKControlFileLockId;
4545
SPINLOCKXidGenLockId;
4646

47-
externboolReleaseDataFile(void);
48-
4947
externVariableCacheShmemVariableCache;
5048

5149
#defineMinXLOGbuffers4
@@ -738,22 +736,13 @@ XLogFileInit(uint32 log, uint32 seg)
738736
XLogFileName(path,log,seg);
739737
unlink(path);
740738

741-
tryAgain:
742739
#ifndef__CYGWIN__
743-
fd=open(path,O_RDWR |O_CREAT |O_EXCL,S_IRUSR |S_IWUSR);
740+
fd=BasicOpenFile(path,O_RDWR |O_CREAT |O_EXCL,S_IRUSR |S_IWUSR);
744741
#else
745-
fd=open(path,O_RDWR |O_CREAT |O_EXCL |O_BINARY,S_IRUSR |S_IWUSR);
742+
fd=BasicOpenFile(path,O_RDWR |O_CREAT |O_EXCL |O_BINARY,S_IRUSR |S_IWUSR);
746743
#endif
747-
if (fd<0&& (errno==EMFILE||errno==ENFILE))
748-
{
749-
fd=errno;
750-
if (!ReleaseDataFile())
751-
elog(STOP,"Create(logfile %u seg %u) failed: %d (and no one data file can be closed)",
752-
logId,logSeg,fd);
753-
gototryAgain;
754-
}
755744
if (fd<0)
756-
elog(STOP,"Init(logfile %u seg %u) failed: %d",
745+
elog(STOP,"Open(logfile %u seg %u) failed: %d",
757746
logId,logSeg,errno);
758747

759748
if (lseek(fd,XLogSegSize-1,SEEK_SET)!= (off_t) (XLogSegSize-1))
@@ -783,20 +772,11 @@ XLogFileOpen(uint32 log, uint32 seg, bool econt)
783772

784773
XLogFileName(path,log,seg);
785774

786-
tryAgain:
787775
#ifndef__CYGWIN__
788-
fd=open(path,O_RDWR);
776+
fd=BasicOpenFile(path,O_RDWR,S_IRUSR |S_IWUSR);
789777
#else
790-
fd=open(path,O_RDWR |O_BINARY);
778+
fd=BasicOpenFile(path,O_RDWR |O_BINARY,S_IRUSR |S_IWUSR);
791779
#endif
792-
if (fd<0&& (errno==EMFILE||errno==ENFILE))
793-
{
794-
fd=errno;
795-
if (!ReleaseDataFile())
796-
elog(STOP,"Open(logfile %u seg %u) failed: %d (and no one data file can be closed)",
797-
logId,logSeg,fd);
798-
gototryAgain;
799-
}
800780
if (fd<0)
801781
{
802782
if (econt&&errno==ENOENT)
@@ -1102,20 +1082,11 @@ UpdateControlFile()
11021082
{
11031083
intfd;
11041084

1105-
tryAgain:
11061085
#ifndef__CYGWIN__
1107-
fd=open(ControlFilePath,O_RDWR);
1086+
fd=BasicOpenFile(ControlFilePath,O_RDWR,S_IRUSR |S_IWUSR);
11081087
#else
1109-
fd=open(ControlFilePath,O_RDWR |O_BINARY);
1088+
fd=BasicOpenFile(ControlFilePath,O_RDWR |O_BINARY,S_IRUSR |S_IWUSR);
11101089
#endif
1111-
if (fd<0&& (errno==EMFILE||errno==ENFILE))
1112-
{
1113-
fd=errno;
1114-
if (!ReleaseDataFile())
1115-
elog(STOP,"Open(cntlfile) failed: %d (and no one data file can be closed)",
1116-
fd);
1117-
gototryAgain;
1118-
}
11191090
if (fd<0)
11201091
elog(STOP,"Open(cntlfile) failed: %d",errno);
11211092

@@ -1174,9 +1145,9 @@ BootStrapXLOG()
11741145
#endif
11751146

11761147
#ifndef__CYGWIN__
1177-
fd=open(ControlFilePath,O_RDWR |O_CREAT |O_EXCL,S_IRUSR |S_IWUSR);
1148+
fd=BasicOpenFile(ControlFilePath,O_RDWR |O_CREAT |O_EXCL,S_IRUSR |S_IWUSR);
11781149
#else
1179-
fd=open(ControlFilePath,O_RDWR |O_CREAT |O_EXCL |O_BINARY,S_IRUSR |S_IWUSR);
1150+
fd=BasicOpenFile(ControlFilePath,O_RDWR |O_CREAT |O_EXCL |O_BINARY,S_IRUSR |S_IWUSR);
11801151
#endif
11811152
if (fd<0)
11821153
elog(STOP,"BootStrapXLOG failed to create control file (%s): %d",
@@ -1288,20 +1259,11 @@ StartupXLOG()
12881259
/*
12891260
* Open/read Control file
12901261
*/
1291-
tryAgain:
12921262
#ifndef__CYGWIN__
1293-
fd=open(ControlFilePath,O_RDWR);
1263+
fd=BasicOpenFile(ControlFilePath,O_RDWR,S_IRUSR |S_IWUSR);
12941264
#else
1295-
fd=open(ControlFilePath,O_RDWR |O_BINARY);
1265+
fd=BasicOpenFile(ControlFilePath,O_RDWR |O_BINARY,S_IRUSR |S_IWUSR);
12961266
#endif
1297-
if (fd<0&& (errno==EMFILE||errno==ENFILE))
1298-
{
1299-
fd=errno;
1300-
if (!ReleaseDataFile())
1301-
elog(STOP,"Open(\"%s\") failed: %d (and no one data file can be closed)",
1302-
ControlFilePath,fd);
1303-
gototryAgain;
1304-
}
13051267
if (fd<0)
13061268
elog(STOP,"Open(\"%s\") failed: %d",ControlFilePath,errno);
13071269

‎src/backend/commands/user.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
9-
* $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.56 2000/05/30 00:49:44 momjian Exp $
9+
* $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.57 2000/06/02 03:58:33 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -146,13 +146,13 @@ write_password_file(Relation rel)
146146
/*
147147
* Create a flag file the postmaster will detect the next time it
148148
* tries to authenticate a user. The postmaster will know to reload
149-
* the pg_pwd file contents. Note: we used to elog(ERROR) if the
150-
*creat() call failed, but it's a little silly to abort the transaction
149+
* the pg_pwd file contents. Note: we used to elog(ERROR) if the file
150+
*creation failed, but it's a little silly to abort the transaction
151151
* at this point, so let's just make it a NOTICE.
152152
*/
153153
filename=crypt_getpwdreloadfilename();
154-
flagfd=creat(filename,S_IRUSR |S_IWUSR);
155-
if (flagfd==-1)
154+
flagfd=BasicOpenFile(filename,O_WRONLY |O_CREAT,0600);
155+
if (flagfd<0)
156156
elog(NOTICE,"%s: %m",filename);
157157
else
158158
close(flagfd);

‎src/backend/storage/file/fd.c

Lines changed: 46 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/storage/file/fd.c,v 1.57 2000/05/31 00:28:27 petere Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/storage/file/fd.c,v 1.58 2000/06/02 03:58:32 tgl Exp $
1111
*
1212
* NOTES:
1313
*
@@ -202,6 +202,45 @@ pg_fsync(int fd)
202202
return0;
203203
}
204204

205+
/*
206+
* BasicOpenFile --- same as open(2) except can free other FDs if needed
207+
*
208+
* This is exported for use by places that really want a plain kernel FD,
209+
* but need to be proof against running out of FDs. Once an FD has been
210+
* successfully returned, it is the caller's responsibility to ensure that
211+
* it will not be leaked on elog()! Most users should *not* call this
212+
* routine directly, but instead use the VFD abstraction level, which
213+
* provides protection against descriptor leaks as well as management of
214+
* files that need to be open for more than a short period of time.
215+
*
216+
* Ideally this should be the *only* direct call of open() in the backend.
217+
* In practice, the postmaster calls open() directly, and there are some
218+
* direct open() calls done early in backend startup. Those are OK since
219+
* this module wouldn't have any open files to close at that point anyway.
220+
*/
221+
int
222+
BasicOpenFile(FileNamefileName,intfileFlags,intfileMode)
223+
{
224+
intfd;
225+
226+
tryAgain:
227+
fd=open(fileName,fileFlags,fileMode);
228+
229+
if (fd >=0)
230+
returnfd;/* success! */
231+
232+
if ((errno==EMFILE||errno==ENFILE)&&nfile>0)
233+
{
234+
DO_DB(elog(DEBUG,"BasicOpenFile: not enough descs, retry, er= %d",
235+
errno));
236+
errno=0;
237+
ReleaseLruFile();
238+
gototryAgain;
239+
}
240+
241+
return-1;/* failure */
242+
}
243+
205244
/*
206245
* pg_nofile: determine number of filedescriptors that fd.c is allowed to use
207246
*/
@@ -348,7 +387,6 @@ LruInsert(File file)
348387

349388
if (FileIsNotOpen(file))
350389
{
351-
352390
while (nfile+numAllocatedFiles >=pg_nofile())
353391
ReleaseLruFile();
354392

@@ -357,15 +395,8 @@ LruInsert(File file)
357395
* to overall system file table being full. So, be prepared to
358396
* release another FD if necessary...
359397
*/
360-
tryAgain:
361-
vfdP->fd=open(vfdP->fileName,vfdP->fileFlags,vfdP->fileMode);
362-
if (vfdP->fd<0&& (errno==EMFILE||errno==ENFILE))
363-
{
364-
errno=0;
365-
ReleaseLruFile();
366-
gototryAgain;
367-
}
368-
398+
vfdP->fd=BasicOpenFile(vfdP->fileName,vfdP->fileFlags,
399+
vfdP->fileMode);
369400
if (vfdP->fd<0)
370401
{
371402
DO_DB(elog(DEBUG,"RE_OPEN FAILED: %d",
@@ -411,22 +442,6 @@ ReleaseLruFile()
411442
LruDelete(VfdCache[0].lruMoreRecently);
412443
}
413444

414-
/*
415-
* Force one kernel file descriptor to be released (temporarily).
416-
*/
417-
bool
418-
ReleaseDataFile()
419-
{
420-
DO_DB(elog(DEBUG,"ReleaseDataFile. Opened %d",nfile));
421-
422-
if (nfile <=0)
423-
return (false);
424-
Assert(VfdCache[0].lruMoreRecently!=0);
425-
LruDelete(VfdCache[0].lruMoreRecently);
426-
427-
return (true);
428-
}
429-
430445
staticFile
431446
AllocateVfd()
432447
{
@@ -617,16 +632,7 @@ fileNameOpenFile(FileName fileName,
617632
while (nfile+numAllocatedFiles >=pg_nofile())
618633
ReleaseLruFile();
619634

620-
tryAgain:
621-
vfdP->fd=open(fileName,fileFlags,fileMode);
622-
if (vfdP->fd<0&& (errno==EMFILE||errno==ENFILE))
623-
{
624-
DO_DB(elog(DEBUG,"fileNameOpenFile: not enough descs, retry, er= %d",
625-
errno));
626-
errno=0;
627-
ReleaseLruFile();
628-
gototryAgain;
629-
}
635+
vfdP->fd=BasicOpenFile(fileName,fileFlags,fileMode);
630636

631637
if (vfdP->fd<0)
632638
{
@@ -990,6 +996,8 @@ FileMarkDirty(File file)
990996
* fd.c will automatically close all files opened with AllocateFile at
991997
* transaction commit or abort; this prevents FD leakage if a routine
992998
* that calls AllocateFile is terminated prematurely by elog(ERROR).
999+
*
1000+
* Ideally this should be the *only* direct call of fopen() in the backend.
9931001
*/
9941002

9951003
FILE*
@@ -1005,7 +1013,7 @@ AllocateFile(char *name, char *mode)
10051013
TryAgain:
10061014
if ((file=fopen(name,mode))==NULL)
10071015
{
1008-
if (errno==EMFILE||errno==ENFILE)
1016+
if ((errno==EMFILE||errno==ENFILE)&&nfile>0)
10091017
{
10101018
DO_DB(elog(DEBUG,"AllocateFile: not enough descs, retry, er= %d",
10111019
errno));

‎src/backend/storage/smgr/md.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/storage/smgr/md.c,v 1.68 2000/05/25 23:30:20 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/storage/smgr/md.c,v 1.69 2000/06/02 03:58:33 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1129,10 +1129,11 @@ _mdfd_blind_getseg(char *dbname, char *relname, Oid dbid, Oid relid,
11291129
}
11301130
#endif
11311131

1132+
/* call fd.c to allow other FDs to be closed if needed */
11321133
#ifndef__CYGWIN32__
1133-
fd=open(path,O_RDWR,0600);
1134+
fd=BasicOpenFile(path,O_RDWR,0600);
11341135
#else
1135-
fd=open(path,O_RDWR |O_BINARY,0600);
1136+
fd=BasicOpenFile(path,O_RDWR |O_BINARY,0600);
11361137
#endif
11371138

11381139
if (fd<0)

‎src/include/storage/fd.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Id: fd.h,v 1.21 2000/04/12 17:16:51 momjian Exp $
10+
* $Id: fd.h,v 1.22 2000/06/02 03:58:31 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -22,7 +22,7 @@
2222
* Use them for all file activity...
2323
*
2424
*File fd;
25-
*fd = FilePathOpenFile("foo", O_RDONLY);
25+
*fd = FilePathOpenFile("foo", O_RDONLY, 0600);
2626
*
2727
*AllocateFile();
2828
*FreeFile();
@@ -64,8 +64,10 @@ extern void FileMarkDirty(File file);
6464
externFILE*AllocateFile(char*name,char*mode);
6565
externvoidFreeFile(FILE*);
6666

67+
/* If you've really really gotta have a plain kernel FD, use this */
68+
externintBasicOpenFile(FileNamefileName,intfileFlags,intfileMode);
69+
6770
/* Miscellaneous support routines */
68-
externboolReleaseDataFile(void);
6971
externvoidcloseAllVfds(void);
7072
externvoidAtEOXact_Files(void);
7173
externintpg_fsync(intfd);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp