~ubuntu-branches/ubuntu/oneiric/postgresql-9.1/oneiric-security

« back to all changes in this revision

Viewing changes to src/backend/storage/ipc/ipci.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2011-05-11 10:41:53 UTC
  • Revision ID: james.westby@ubuntu.com-20110511104153-psbh2o58553fv1m0
Tags: upstream-9.1~beta1
ImportĀ upstreamĀ versionĀ 9.1~beta1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*-------------------------------------------------------------------------
 
2
 *
 
3
 * ipci.c
 
4
 *        POSTGRES inter-process communication initialization code.
 
5
 *
 
6
 * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
 
7
 * Portions Copyright (c) 1994, Regents of the University of California
 
8
 *
 
9
 *
 
10
 * IDENTIFICATION
 
11
 *        src/backend/storage/ipc/ipci.c
 
12
 *
 
13
 *-------------------------------------------------------------------------
 
14
 */
 
15
#include "postgres.h"
 
16
 
 
17
#include "access/clog.h"
 
18
#include "access/heapam.h"
 
19
#include "access/multixact.h"
 
20
#include "access/nbtree.h"
 
21
#include "access/subtrans.h"
 
22
#include "access/twophase.h"
 
23
#include "commands/async.h"
 
24
#include "miscadmin.h"
 
25
#include "pgstat.h"
 
26
#include "postmaster/autovacuum.h"
 
27
#include "postmaster/bgwriter.h"
 
28
#include "postmaster/postmaster.h"
 
29
#include "replication/walreceiver.h"
 
30
#include "replication/walsender.h"
 
31
#include "storage/bufmgr.h"
 
32
#include "storage/ipc.h"
 
33
#include "storage/pg_shmem.h"
 
34
#include "storage/pmsignal.h"
 
35
#include "storage/predicate.h"
 
36
#include "storage/procarray.h"
 
37
#include "storage/procsignal.h"
 
38
#include "storage/sinvaladt.h"
 
39
#include "storage/spin.h"
 
40
 
 
41
 
 
42
shmem_startup_hook_type shmem_startup_hook = NULL;
 
43
 
 
44
static Size total_addin_request = 0;
 
45
static bool addin_request_allowed = true;
 
46
 
 
47
 
 
48
/*
 
49
 * RequestAddinShmemSpace
 
50
 *              Request that extra shmem space be allocated for use by
 
51
 *              a loadable module.
 
52
 *
 
53
 * This is only useful if called from the _PG_init hook of a library that
 
54
 * is loaded into the postmaster via shared_preload_libraries.  Once
 
55
 * shared memory has been allocated, calls will be ignored.  (We could
 
56
 * raise an error, but it seems better to make it a no-op, so that
 
57
 * libraries containing such calls can be reloaded if needed.)
 
58
 */
 
59
void
 
60
RequestAddinShmemSpace(Size size)
 
61
{
 
62
        if (IsUnderPostmaster || !addin_request_allowed)
 
63
                return;                                 /* too late */
 
64
        total_addin_request = add_size(total_addin_request, size);
 
65
}
 
66
 
 
67
 
 
68
/*
 
69
 * CreateSharedMemoryAndSemaphores
 
70
 *              Creates and initializes shared memory and semaphores.
 
71
 *
 
72
 * This is called by the postmaster or by a standalone backend.
 
73
 * It is also called by a backend forked from the postmaster in the
 
74
 * EXEC_BACKEND case.  In the latter case, the shared memory segment
 
75
 * already exists and has been physically attached to, but we have to
 
76
 * initialize pointers in local memory that reference the shared structures,
 
77
 * because we didn't inherit the correct pointer values from the postmaster
 
78
 * as we do in the fork() scenario.  The easiest way to do that is to run
 
79
 * through the same code as before.  (Note that the called routines mostly
 
80
 * check IsUnderPostmaster, rather than EXEC_BACKEND, to detect this case.
 
81
 * This is a bit code-wasteful and could be cleaned up.)
 
82
 *
 
83
 * If "makePrivate" is true then we only need private memory, not shared
 
84
 * memory.      This is true for a standalone backend, false for a postmaster.
 
85
 */
 
86
void
 
87
CreateSharedMemoryAndSemaphores(bool makePrivate, int port)
 
88
{
 
89
        if (!IsUnderPostmaster)
 
90
        {
 
91
                PGShmemHeader *seghdr;
 
92
                Size            size;
 
93
                int                     numSemas;
 
94
 
 
95
                /*
 
96
                 * Size of the Postgres shared-memory block is estimated via
 
97
                 * moderately-accurate estimates for the big hogs, plus 100K for the
 
98
                 * stuff that's too small to bother with estimating.
 
99
                 *
 
100
                 * We take some care during this phase to ensure that the total size
 
101
                 * request doesn't overflow size_t.  If this gets through, we don't
 
102
                 * need to be so careful during the actual allocation phase.
 
103
                 */
 
104
                size = 100000;
 
105
                size = add_size(size, hash_estimate_size(SHMEM_INDEX_SIZE,
 
106
                                                                                                 sizeof(ShmemIndexEnt)));
 
107
                size = add_size(size, BufferShmemSize());
 
108
                size = add_size(size, LockShmemSize());
 
109
                size = add_size(size, PredicateLockShmemSize());
 
110
                size = add_size(size, ProcGlobalShmemSize());
 
111
                size = add_size(size, XLOGShmemSize());
 
112
                size = add_size(size, CLOGShmemSize());
 
113
                size = add_size(size, SUBTRANSShmemSize());
 
114
                size = add_size(size, TwoPhaseShmemSize());
 
115
                size = add_size(size, MultiXactShmemSize());
 
116
                size = add_size(size, LWLockShmemSize());
 
117
                size = add_size(size, ProcArrayShmemSize());
 
118
                size = add_size(size, BackendStatusShmemSize());
 
119
                size = add_size(size, SInvalShmemSize());
 
120
                size = add_size(size, PMSignalShmemSize());
 
121
                size = add_size(size, ProcSignalShmemSize());
 
122
                size = add_size(size, BgWriterShmemSize());
 
123
                size = add_size(size, AutoVacuumShmemSize());
 
124
                size = add_size(size, WalSndShmemSize());
 
125
                size = add_size(size, WalRcvShmemSize());
 
126
                size = add_size(size, BTreeShmemSize());
 
127
                size = add_size(size, SyncScanShmemSize());
 
128
                size = add_size(size, AsyncShmemSize());
 
129
#ifdef EXEC_BACKEND
 
130
                size = add_size(size, ShmemBackendArraySize());
 
131
#endif
 
132
 
 
133
                /* freeze the addin request size and include it */
 
134
                addin_request_allowed = false;
 
135
                size = add_size(size, total_addin_request);
 
136
 
 
137
                /* might as well round it off to a multiple of a typical page size */
 
138
                size = add_size(size, 8192 - (size % 8192));
 
139
 
 
140
                elog(DEBUG3, "invoking IpcMemoryCreate(size=%lu)",
 
141
                         (unsigned long) size);
 
142
 
 
143
                /*
 
144
                 * Create the shmem segment
 
145
                 */
 
146
                seghdr = PGSharedMemoryCreate(size, makePrivate, port);
 
147
 
 
148
                InitShmemAccess(seghdr);
 
149
 
 
150
                /*
 
151
                 * Create semaphores
 
152
                 */
 
153
                numSemas = ProcGlobalSemas();
 
154
                numSemas += SpinlockSemas();
 
155
                PGReserveSemaphores(numSemas, port);
 
156
        }
 
157
        else
 
158
        {
 
159
                /*
 
160
                 * We are reattaching to an existing shared memory segment. This
 
161
                 * should only be reached in the EXEC_BACKEND case, and even then only
 
162
                 * with makePrivate == false.
 
163
                 */
 
164
#ifdef EXEC_BACKEND
 
165
                Assert(!makePrivate);
 
166
#else
 
167
                elog(PANIC, "should be attached to shared memory already");
 
168
#endif
 
169
        }
 
170
 
 
171
        /*
 
172
         * Set up shared memory allocation mechanism
 
173
         */
 
174
        if (!IsUnderPostmaster)
 
175
                InitShmemAllocation();
 
176
 
 
177
        /*
 
178
         * Now initialize LWLocks, which do shared memory allocation and are
 
179
         * needed for InitShmemIndex.
 
180
         */
 
181
        if (!IsUnderPostmaster)
 
182
                CreateLWLocks();
 
183
 
 
184
        /*
 
185
         * Set up shmem.c index hashtable
 
186
         */
 
187
        InitShmemIndex();
 
188
 
 
189
        /*
 
190
         * Set up xlog, clog, and buffers
 
191
         */
 
192
        XLOGShmemInit();
 
193
        CLOGShmemInit();
 
194
        SUBTRANSShmemInit();
 
195
        TwoPhaseShmemInit();
 
196
        MultiXactShmemInit();
 
197
        InitBufferPool();
 
198
 
 
199
        /*
 
200
         * Set up lock manager
 
201
         */
 
202
        InitLocks();
 
203
 
 
204
        /*
 
205
         * Set up predicate lock manager
 
206
         */
 
207
        InitPredicateLocks();
 
208
 
 
209
        /*
 
210
         * Set up process table
 
211
         */
 
212
        if (!IsUnderPostmaster)
 
213
                InitProcGlobal();
 
214
        CreateSharedProcArray();
 
215
        CreateSharedBackendStatus();
 
216
 
 
217
        /*
 
218
         * Set up shared-inval messaging
 
219
         */
 
220
        CreateSharedInvalidationState();
 
221
 
 
222
        /*
 
223
         * Set up interprocess signaling mechanisms
 
224
         */
 
225
        PMSignalShmemInit();
 
226
        ProcSignalShmemInit();
 
227
        BgWriterShmemInit();
 
228
        AutoVacuumShmemInit();
 
229
        WalSndShmemInit();
 
230
        WalRcvShmemInit();
 
231
 
 
232
        /*
 
233
         * Set up other modules that need some shared memory space
 
234
         */
 
235
        BTreeShmemInit();
 
236
        SyncScanShmemInit();
 
237
        AsyncShmemInit();
 
238
 
 
239
#ifdef EXEC_BACKEND
 
240
 
 
241
        /*
 
242
         * Alloc the win32 shared backend array
 
243
         */
 
244
        if (!IsUnderPostmaster)
 
245
                ShmemBackendArrayAllocation();
 
246
#endif
 
247
 
 
248
        /*
 
249
         * Now give loadable modules a chance to set up their shmem allocations
 
250
         */
 
251
        if (shmem_startup_hook)
 
252
                shmem_startup_hook();
 
253
}