Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 626eca6

Browse files
committed
This patch reserves the last superuser_reserved_connections slots for
connections by the superuser only. This patch replaces the last patch I sent a couple of days ago. It closes a connection that has not been authorised by a superuser if it would leave less than the GUC variable ReservedBackends (superuser_reserved_connections in postgres.conf) backend process slots free in the SISeg. This differs to the first patch which only reserved the last ReservedBackends slots in the procState array. This has made the free slot test more expensive due to the use of a lock. After thinking about a comment on the first patch I've also made it a fatal error if the number of reserved slots is not less than the maximum number of connections. Nigel J. Andrews
1 parent 1761990 commit 626eca6

File tree

9 files changed

+90
-21
lines changed

9 files changed

+90
-21
lines changed

src/backend/postmaster/postmaster.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
*
3838
*
3939
* IDENTIFICATION
40-
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.285 2002/08/18 03:03:25 momjian Exp $
40+
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.286 2002/08/29 21:02:12 momjian Exp $
4141
*
4242
* NOTES
4343
*
@@ -151,6 +151,18 @@ char *VirtualHost;
151151
*/
152152
int MaxBackends = DEF_MAXBACKENDS;
153153

154+
/*
155+
* ReservedBackends is the number of backends reserved for superuser use.
156+
* This number is taken out of the pool size given by MaxBackends so
157+
* number of backend slots available to none super users is
158+
* (MaxBackends - ReservedBackends). Note, existing super user
159+
* connections are not taken into account once this lower limit has
160+
* been reached, i.e. superuser connections made before the lower limit
161+
* is reached always count towards that limit and are not taken from
162+
* ReservedBackends.
163+
*/
164+
int ReservedBackends = 2;
165+
154166

155167
static char *progname = (char *) NULL;
156168

@@ -567,6 +579,12 @@ PostmasterMain(int argc, char *argv[])
567579

568580
ProcessConfigFile(PGC_POSTMASTER);
569581

582+
/*
583+
* Force an exit if ReservedBackends is not less than MaxBackends.
584+
*/
585+
if (ReservedBackends >= MaxBackends)
586+
elog(FATAL,"superuser_reserved_connections must be less than max_connections.");
587+
570588
/*
571589
* Now that we are done processing the postmaster arguments, reset
572590
* getopt(3) library so that it will work correctly in subprocesses.

src/backend/storage/ipc/sinval.c

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinval.c,v 1.49 2002/06/20 20:29:35 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinval.c,v 1.50 2002/08/29 21:02:12 momjian Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -538,3 +538,27 @@ BackendIdGetProc(BackendId procId)
538538

539539
return NULL;
540540
}
541+
542+
/*
543+
* CountEmptyBackendSlots - count empty slots in backend process table
544+
*
545+
* Doesn't count since the procState array could be large and we've already
546+
* allowed for that by running a freeBackends counter in the SI segment.
547+
* Unlike CountActiveBackends() we do not need to interrogate the
548+
* backends to determine the free slot count.
549+
* Goes for a lock despite being a trival look up in case other backends
550+
* are busy starting or exiting since there is scope for confusion.
551+
*/
552+
int
553+
CountEmptyBackendSlots(void)
554+
{
555+
int count;
556+
557+
LWLockAcquire(SInvalLock, LW_SHARED);
558+
559+
count = shmInvalBuffer->freeBackends;
560+
561+
LWLockRelease(SInvalLock);
562+
563+
return count;
564+
}

src/backend/storage/ipc/sinvaladt.c

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinvaladt.c,v 1.47 2002/06/20 20:29:35 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinvaladt.c,v 1.48 2002/08/29 21:02:12 momjian Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -60,6 +60,7 @@ SIBufferInit(int maxBackends)
6060
segP->maxMsgNum = 0;
6161
segP->lastBackend = 0;
6262
segP->maxBackends = maxBackends;
63+
segP->freeBackends = maxBackends;
6364

6465
/* The buffer[] array is initially all unused, so we need not fill it */
6566

@@ -91,6 +92,13 @@ SIBackendInit(SISeg *segP)
9192
int index;
9293
ProcState *stateP = NULL;
9394

95+
if (segP->freeBackends == 0)
96+
{
97+
/* out of procState slots */
98+
MyBackendId = InvalidBackendId;
99+
return 0;
100+
}
101+
94102
/* Look for a free entry in the procState array */
95103
for (index = 0; index < segP->lastBackend; index++)
96104
{
@@ -103,18 +111,9 @@ SIBackendInit(SISeg *segP)
103111

104112
if (stateP == NULL)
105113
{
106-
if (segP->lastBackend < segP->maxBackends)
107-
{
108-
stateP = &segP->procState[segP->lastBackend];
109-
Assert(stateP->nextMsgNum < 0);
110-
segP->lastBackend++;
111-
}
112-
else
113-
{
114-
/* out of procState slots */
115-
MyBackendId = InvalidBackendId;
116-
return 0;
117-
}
114+
stateP = &segP->procState[segP->lastBackend];
115+
Assert(stateP->nextMsgNum < 0);
116+
segP->lastBackend++;
118117
}
119118

120119
MyBackendId = (stateP - &segP->procState[0]) + 1;
@@ -123,6 +122,9 @@ SIBackendInit(SISeg *segP)
123122
elog(DEBUG1, "SIBackendInit: backend id %d", MyBackendId);
124123
#endif /* INVALIDDEBUG */
125124

125+
/* Reduce free slot count */
126+
segP->freeBackends--;
127+
126128
/* mark myself active, with all extant messages already read */
127129
stateP->nextMsgNum = segP->maxMsgNum;
128130
stateP->resetState = false;
@@ -166,6 +168,9 @@ CleanupInvalidationState(int status, Datum arg)
166168
}
167169
segP->lastBackend = i;
168170

171+
/* Adjust free slot count */
172+
segP->freeBackends++;
173+
169174
LWLockRelease(SInvalLock);
170175
}
171176

src/backend/utils/init/postinit.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.110 2002/08/29 07:22:28 ishii Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.111 2002/08/29 21:02:12 momjian Exp $
1212
*
1313
*
1414
*-------------------------------------------------------------------------
@@ -395,6 +395,16 @@ InitPostgres(const char *dbname, const char *username)
395395
/* close the transaction we started above */
396396
if (!bootstrap)
397397
CommitTransactionCommand();
398+
399+
/*
400+
* Check a normal user hasn't connected to a superuser reserved slot.
401+
* Do this here since we need the user information and that only happens
402+
* after we've started bringing the shared memory online. So we wait
403+
* until we've registered exit handlers and potentially shut an open
404+
* transaction down for an as safety conscious rejection as possible.
405+
*/
406+
if (CountEmptyBackendSlots() < ReservedBackends && !superuser())
407+
elog(ERROR, "Non-superuser connection limit exceeded");
398408
}
399409

400410
/*

src/backend/utils/misc/guc.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* command, configuration file, and command line options.
66
* See src/backend/utils/misc/README for more information.
77
*
8-
* $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.86 2002/08/29 17:14:33 tgl Exp $
8+
* $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.87 2002/08/29 21:02:12 momjian Exp $
99
*
1010
* Copyright 2000 by PostgreSQL Global Development Group
1111
* Written by Peter Eisentraut <peter_e@gmx.net>.
@@ -537,13 +537,20 @@ static struct config_int
537537
/*
538538
* Note: There is some postprocessing done in PostmasterMain() to make
539539
* sure the buffers are at least twice the number of backends, so the
540-
* constraints here are partially unused.
540+
* constraints here are partially unused. Similarly, the superuser
541+
* reserved number is checked to ensure it is less than the max
542+
* backends number.
541543
*/
542544
{
543545
{ "max_connections", PGC_POSTMASTER }, &MaxBackends,
544546
DEF_MAXBACKENDS, 1, INT_MAX, NULL, NULL
545547
},
546548

549+
{
550+
{ "superuser_reserved_connections", PGC_POSTMASTER }, &ReservedBackends,
551+
2, 0, INT_MAX, NULL, NULL
552+
},
553+
547554
{
548555
{ "shared_buffers", PGC_POSTMASTER }, &NBuffers,
549556
DEF_NBUFFERS, 16, INT_MAX, NULL, NULL

src/backend/utils/misc/postgresql.conf.sample

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#ssl = false
3232

3333
#max_connections = 32
34+
#superuser_reserved_connections = 2
3435

3536
#port = 5432
3637
#hostname_lookup = false

src/include/miscadmin.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
1313
* Portions Copyright (c) 1994, Regents of the University of California
1414
*
15-
* $Id: miscadmin.h,v 1.106 2002/06/20 20:29:42 momjian Exp $
15+
* $Id: miscadmin.h,v 1.107 2002/08/29 21:02:12 momjian Exp $
1616
*
1717
* NOTES
1818
* some of the information in this file should be moved to
@@ -179,6 +179,7 @@ extern bool NetServer;
179179
extern bool EnableSSL;
180180
extern bool SilentMode;
181181
extern int MaxBackends;
182+
extern int ReservedBackends;
182183
extern int NBuffers;
183184
extern int PostPortNumber;
184185
extern int Unix_socket_permissions;

src/include/storage/sinval.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Id: sinval.h,v 1.28 2002/06/20 20:29:52 momjian Exp $
10+
* $Id: sinval.h,v 1.29 2002/08/29 21:02:12 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -89,4 +89,6 @@ extern int CountActiveBackends(void);
8989
/* Use "struct PGPROC", not PGPROC, to avoid including proc.h here */
9090
extern struct PGPROC *BackendIdGetProc(BackendId procId);
9191

92+
extern int CountEmptyBackendSlots(void);
93+
9294
#endif /* SINVAL_H */

src/include/storage/sinvaladt.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Id: sinvaladt.h,v 1.32 2002/06/20 20:29:52 momjian Exp $
10+
* $Id: sinvaladt.h,v 1.33 2002/08/29 21:02:12 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -85,6 +85,7 @@ typedef struct SISeg
8585
int lastBackend; /* index of last active procState entry,
8686
* +1 */
8787
int maxBackends; /* size of procState array */
88+
int freeBackends; /* number of empty procState slots */
8889

8990
/*
9091
* Circular buffer holding shared-inval messages

0 commit comments

Comments
 (0)