@@ -255,29 +255,22 @@ pgstat_beinit(void)
255255
256256
257257/* ----------
258- * pgstat_bestart () -
258+ * pgstat_bestart_initial () -
259259 *
260- * Initialize this backend's entry in the PgBackendStatus array.
261- * Called from InitPostgres.
260+ * Initialize this backend's entry in the PgBackendStatus array. Called
261+ * from InitPostgres and AuxiliaryProcessMain .
262262 *
263- * Apart from auxiliary processes, MyDatabaseId, session userid, and
264- * application_name must already be set (hence, this cannot be combined
265- * with pgstat_beinit). Note also that we must be inside a transaction
266- * if this isn't an aux process, as we may need to do encoding conversion
267- * on some strings.
268- *----------
263+ * Clears out a new pgstat entry, initializing it to suitable defaults and
264+ * reporting STATE_STARTING. Backends should continue filling in any
265+ * transport security details as needed with pgstat_bestart_security(), and
266+ * must finally exit STATE_STARTING by calling pgstat_bestart_final().
267+ * ----------
269268 */
270269void
271- pgstat_bestart (void )
270+ pgstat_bestart_initial (void )
272271{
273272 volatile PgBackendStatus * vbeentry = MyBEEntry ;
274273 PgBackendStatus lbeentry ;
275- #ifdef USE_SSL
276- PgBackendSSLStatus lsslstatus ;
277- #endif
278- #ifdef ENABLE_GSS
279- PgBackendGSSStatus lgssstatus ;
280- #endif
281274
282275 /* pgstats state must be initialized from pgstat_beinit() */
283276 Assert (vbeentry != NULL );
@@ -297,14 +290,6 @@ pgstat_bestart(void)
297290 unvolatize (PgBackendStatus * , vbeentry ),
298291 sizeof (PgBackendStatus ));
299292
300- /* These structs can just start from zeroes each time, though */
301- #ifdef USE_SSL
302- memset (& lsslstatus , 0 , sizeof (lsslstatus ));
303- #endif
304- #ifdef ENABLE_GSS
305- memset (& lgssstatus , 0 , sizeof (lgssstatus ));
306- #endif
307-
308293 /*
309294 * Now fill in all the fields of lbeentry, except for strings that are
310295 * out-of-line data. Those have to be handled separately, below.
@@ -315,15 +300,8 @@ pgstat_bestart(void)
315300 lbeentry .st_activity_start_timestamp = 0 ;
316301 lbeentry .st_state_start_timestamp = 0 ;
317302 lbeentry .st_xact_start_timestamp = 0 ;
318- lbeentry .st_databaseid = MyDatabaseId ;
319-
320- /* We have userid for client-backends, wal-sender and bgworker processes */
321- if (lbeentry .st_backendType == B_BACKEND
322- || lbeentry .st_backendType == B_WAL_SENDER
323- || lbeentry .st_backendType == B_BG_WORKER )
324- lbeentry .st_userid = GetSessionUserId ();
325- else
326- lbeentry .st_userid = InvalidOid ;
303+ lbeentry .st_databaseid = InvalidOid ;
304+ lbeentry .st_userid = InvalidOid ;
327305
328306 /*
329307 * We may not have a MyProcPort (eg, if this is the autovacuum process).
@@ -336,46 +314,10 @@ pgstat_bestart(void)
336314 else
337315 MemSet (& lbeentry .st_clientaddr , 0 , sizeof (lbeentry .st_clientaddr ));
338316
339- #ifdef USE_SSL
340- if (MyProcPort && MyProcPort -> ssl_in_use )
341- {
342- lbeentry .st_ssl = true;
343- lsslstatus .ssl_bits = be_tls_get_cipher_bits (MyProcPort );
344- strlcpy (lsslstatus .ssl_version , be_tls_get_version (MyProcPort ), NAMEDATALEN );
345- strlcpy (lsslstatus .ssl_cipher , be_tls_get_cipher (MyProcPort ), NAMEDATALEN );
346- be_tls_get_peer_subject_name (MyProcPort , lsslstatus .ssl_client_dn , NAMEDATALEN );
347- be_tls_get_peer_serial (MyProcPort , lsslstatus .ssl_client_serial , NAMEDATALEN );
348- be_tls_get_peer_issuer_name (MyProcPort , lsslstatus .ssl_issuer_dn , NAMEDATALEN );
349- }
350- else
351- {
352- lbeentry .st_ssl = false;
353- }
354- #else
355317 lbeentry .st_ssl = false;
356- #endif
357-
358- #ifdef ENABLE_GSS
359- if (MyProcPort && MyProcPort -> gss != NULL )
360- {
361- const char * princ = be_gssapi_get_princ (MyProcPort );
362-
363- lbeentry .st_gss = true;
364- lgssstatus .gss_auth = be_gssapi_get_auth (MyProcPort );
365- lgssstatus .gss_enc = be_gssapi_get_enc (MyProcPort );
366- lgssstatus .gss_delegation = be_gssapi_get_delegation (MyProcPort );
367- if (princ )
368- strlcpy (lgssstatus .gss_princ , princ , NAMEDATALEN );
369- }
370- else
371- {
372- lbeentry .st_gss = false;
373- }
374- #else
375318 lbeentry .st_gss = false;
376- #endif
377319
378- lbeentry .st_state = STATE_UNDEFINED ;
320+ lbeentry .st_state = STATE_STARTING ;
379321 lbeentry .st_progress_command = PROGRESS_COMMAND_INVALID ;
380322 lbeentry .st_progress_command_target = InvalidOid ;
381323 lbeentry .st_query_id = UINT64CONST (0 );
@@ -417,14 +359,138 @@ pgstat_bestart(void)
417359 lbeentry .st_clienthostname [NAMEDATALEN - 1 ] = '\0' ;
418360 lbeentry .st_activity_raw [pgstat_track_activity_query_size - 1 ] = '\0' ;
419361
362+ /* These structs can just start from zeroes each time */
420363#ifdef USE_SSL
421- memcpy (lbeentry .st_sslstatus , & lsslstatus , sizeof (PgBackendSSLStatus ));
364+ memset (lbeentry .st_sslstatus , 0 , sizeof (PgBackendSSLStatus ));
422365#endif
423366#ifdef ENABLE_GSS
424- memcpy (lbeentry .st_gssstatus , & lgssstatus , sizeof (PgBackendGSSStatus ));
367+ memset (lbeentry .st_gssstatus , 0 , sizeof (PgBackendGSSStatus ));
425368#endif
426369
427370 PGSTAT_END_WRITE_ACTIVITY (vbeentry );
371+ }
372+
373+ /* ----------
374+ * pgstat_bestart_security() -
375+ *
376+ * Fill in SSL and GSS information for the pgstat entry. This is the second
377+ * optional step taken when filling a backend's entry, not required for
378+ * auxiliary processes.
379+ *
380+ * This should only be called from backends with a MyProcPort.
381+ * ----------
382+ */
383+ void
384+ pgstat_bestart_security (void )
385+ {
386+ volatile PgBackendStatus * beentry = MyBEEntry ;
387+ bool ssl = false;
388+ bool gss = false;
389+ #ifdef USE_SSL
390+ PgBackendSSLStatus lsslstatus ;
391+ PgBackendSSLStatus * st_sslstatus ;
392+ #endif
393+ #ifdef ENABLE_GSS
394+ PgBackendGSSStatus lgssstatus ;
395+ PgBackendGSSStatus * st_gssstatus ;
396+ #endif
397+
398+ /* pgstats state must be initialized from pgstat_beinit() */
399+ Assert (beentry != NULL );
400+ Assert (MyProcPort ); /* otherwise there's no point */
401+
402+ #ifdef USE_SSL
403+ st_sslstatus = beentry -> st_sslstatus ;
404+ memset (& lsslstatus , 0 , sizeof (lsslstatus ));
405+
406+ if (MyProcPort -> ssl_in_use )
407+ {
408+ ssl = true;
409+ lsslstatus .ssl_bits = be_tls_get_cipher_bits (MyProcPort );
410+ strlcpy (lsslstatus .ssl_version , be_tls_get_version (MyProcPort ), NAMEDATALEN );
411+ strlcpy (lsslstatus .ssl_cipher , be_tls_get_cipher (MyProcPort ), NAMEDATALEN );
412+ be_tls_get_peer_subject_name (MyProcPort , lsslstatus .ssl_client_dn , NAMEDATALEN );
413+ be_tls_get_peer_serial (MyProcPort , lsslstatus .ssl_client_serial , NAMEDATALEN );
414+ be_tls_get_peer_issuer_name (MyProcPort , lsslstatus .ssl_issuer_dn , NAMEDATALEN );
415+ }
416+ #endif
417+
418+ #ifdef ENABLE_GSS
419+ st_gssstatus = beentry -> st_gssstatus ;
420+ memset (& lgssstatus , 0 , sizeof (lgssstatus ));
421+
422+ if (MyProcPort -> gss != NULL )
423+ {
424+ const char * princ = be_gssapi_get_princ (MyProcPort );
425+
426+ gss = true;
427+ lgssstatus .gss_auth = be_gssapi_get_auth (MyProcPort );
428+ lgssstatus .gss_enc = be_gssapi_get_enc (MyProcPort );
429+ lgssstatus .gss_delegation = be_gssapi_get_delegation (MyProcPort );
430+ if (princ )
431+ strlcpy (lgssstatus .gss_princ , princ , NAMEDATALEN );
432+ }
433+ #endif
434+
435+ /*
436+ * Update my status entry, following the protocol of bumping
437+ * st_changecount before and after. We use a volatile pointer here to
438+ * ensure the compiler doesn't try to get cute.
439+ */
440+ PGSTAT_BEGIN_WRITE_ACTIVITY (beentry );
441+
442+ beentry -> st_ssl = ssl ;
443+ beentry -> st_gss = gss ;
444+
445+ #ifdef USE_SSL
446+ memcpy (st_sslstatus , & lsslstatus , sizeof (PgBackendSSLStatus ));
447+ #endif
448+ #ifdef ENABLE_GSS
449+ memcpy (st_gssstatus , & lgssstatus , sizeof (PgBackendGSSStatus ));
450+ #endif
451+
452+ PGSTAT_END_WRITE_ACTIVITY (beentry );
453+ }
454+
455+ /* ----------
456+ * pgstat_bestart_final() -
457+ *
458+ * Finalizes the state of this backend's entry by filling in the user and
459+ * database IDs, clearing STATE_STARTING, and reporting the application_name.
460+ *
461+ * We must be inside a transaction if this is not an auxiliary process, as
462+ * we may need to do encoding conversion.
463+ * ----------
464+ */
465+ void
466+ pgstat_bestart_final (void )
467+ {
468+ volatile PgBackendStatus * beentry = MyBEEntry ;
469+ Oid userid ;
470+
471+ /* pgstats state must be initialized from pgstat_beinit() */
472+ Assert (beentry != NULL );
473+
474+ /* We have userid for client-backends, wal-sender and bgworker processes */
475+ if (MyBackendType == B_BACKEND
476+ || MyBackendType == B_WAL_SENDER
477+ || MyBackendType == B_BG_WORKER )
478+ userid = GetSessionUserId ();
479+ else
480+ userid = InvalidOid ;
481+
482+ /*
483+ * Update my status entry, following the protocol of bumping
484+ * st_changecount before and after. We use a volatile pointer here to
485+ * ensure the compiler doesn't try to get cute.
486+ */
487+ PGSTAT_BEGIN_WRITE_ACTIVITY (beentry );
488+
489+ beentry -> st_databaseid = MyDatabaseId ;
490+ beentry -> st_userid = userid ;
491+ beentry -> st_state = STATE_UNDEFINED ;
492+
493+ PGSTAT_END_WRITE_ACTIVITY (beentry );
428494
429495 /* Create the backend statistics entry */
430496 if (pgstat_tracks_backend_bktype (MyBackendType ))
0 commit comments