Skip to content

Commit 8607639

Browse files
committed
Fix coding rules violations in walreceiver.c
1. Since commit b1a9bad we had pstrdup() inside a spinlock-protected critical section; reported by Andreas Seltenreich. Turn those into strlcpy() to stack-allocated variables instead. Backpatch to 9.6. 2. Since commit 9ed551e we had a pfree() uselessly inside a spinlock-protected critical section. Tom Lane noticed in code review. Move down. Backpatch to 9.6. 3. Since commit 6423390 we had GetCurrentTimestamp() (a kernel call) inside a spinlock-protected critical section. Tom Lane noticed in code review. Move it up. Backpatch to 9.2. 4. Since commit 1bb2558 we did elog(PANIC) while holding spinlock. Tom Lane noticed in code review. Release spinlock before dying. Backpatch to 9.2. Discussion: https://postgr.es/m/87h8vhtgj2.fsf@ansel.ydns.eu
1 parent 858e9f2 commit 8607639

File tree

1 file changed

+13
-8
lines changed

1 file changed

+13
-8
lines changed

src/backend/replication/walreceiver.c

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ WalReceiverMain(void)
201201
bool first_stream;
202202
WalRcvData *walrcv = WalRcv;
203203
TimestampTz last_recv_timestamp;
204+
TimestampTz now;
204205
bool ping_sent;
205206

206207
/*
@@ -209,6 +210,8 @@ WalReceiverMain(void)
209210
*/
210211
Assert(walrcv != NULL);
211212

213+
now = GetCurrentTimestamp();
214+
212215
/*
213216
* Mark walreceiver as running in shared memory.
214217
*
@@ -239,6 +242,7 @@ WalReceiverMain(void)
239242
case WALRCV_RESTARTING:
240243
default:
241244
/* Shouldn't happen */
245+
SpinLockRelease(&walrcv->mutex);
242246
elog(PANIC, "walreceiver still running according to shared memory state");
243247
}
244248
/* Advertise our PID so that the startup process can kill us */
@@ -253,7 +257,8 @@ WalReceiverMain(void)
253257
startpointTLI = walrcv->receiveStartTLI;
254258

255259
/* Initialise to a sanish value */
256-
walrcv->lastMsgSendTime = walrcv->lastMsgReceiptTime = walrcv->latestWalEndTime = GetCurrentTimestamp();
260+
walrcv->lastMsgSendTime =
261+
walrcv->lastMsgReceiptTime = walrcv->latestWalEndTime = now;
257262

258263
SpinLockRelease(&walrcv->mutex);
259264

@@ -317,13 +322,13 @@ WalReceiverMain(void)
317322
SpinLockAcquire(&walrcv->mutex);
318323
memset(walrcv->conninfo, 0, MAXCONNINFO);
319324
if (tmp_conninfo)
320-
{
321325
strlcpy((char *) walrcv->conninfo, tmp_conninfo, MAXCONNINFO);
322-
pfree(tmp_conninfo);
323-
}
324326
walrcv->ready_to_display = true;
325327
SpinLockRelease(&walrcv->mutex);
326328

329+
if (tmp_conninfo)
330+
pfree(tmp_conninfo);
331+
327332
first_stream = true;
328333
for (;;)
329334
{
@@ -1349,8 +1354,8 @@ pg_stat_get_wal_receiver(PG_FUNCTION_ARGS)
13491354
TimestampTz last_receipt_time;
13501355
XLogRecPtr latest_end_lsn;
13511356
TimestampTz latest_end_time;
1352-
char *slotname;
1353-
char *conninfo;
1357+
char slotname[NAMEDATALEN];
1358+
char conninfo[MAXCONNINFO];
13541359

13551360
/*
13561361
* No WAL receiver (or not ready yet), just return a tuple with NULL
@@ -1377,8 +1382,8 @@ pg_stat_get_wal_receiver(PG_FUNCTION_ARGS)
13771382
last_receipt_time = walrcv->lastMsgReceiptTime;
13781383
latest_end_lsn = walrcv->latestWalEnd;
13791384
latest_end_time = walrcv->latestWalEndTime;
1380-
slotname = pstrdup(walrcv->slotname);
1381-
conninfo = pstrdup(walrcv->conninfo);
1385+
strlcpy(slotname, (char *) walrcv->slotname, sizeof(slotname));
1386+
strlcpy(conninfo, (char *) walrcv->conninfo, sizeof(conninfo));
13821387
SpinLockRelease(&walrcv->mutex);
13831388

13841389
/* Fetch values */

0 commit comments

Comments
 (0)