@@ -96,24 +96,6 @@ checkControlFile(ControlFileData *ControlFile)
9696 "the PostgreSQL installation would be incompatible with this data directory." );
9797}
9898
99- /*
100- * Verify control file contents in the buffer src, and copy it to *ControlFile.
101- */
102- static void
103- digestControlFile (ControlFileData * ControlFile , char * src , size_t size )
104- {
105- int ControlFileSize = PG_CONTROL_FILE_SIZE ;
106-
107- if (size != ControlFileSize )
108- elog (ERROR , "unexpected control file size %d, expected %d" ,
109- (int ) size , ControlFileSize );
110-
111- memcpy (ControlFile , src , sizeof (ControlFileData ));
112-
113- /* Additional checks on control file */
114- checkControlFile (ControlFile );
115- }
116-
11799/*
118100 * Write ControlFile to pg_control
119101 */
@@ -164,36 +146,70 @@ get_current_timeline(PGconn *conn)
164146 if (PQresultStatus (res ) == PGRES_TUPLES_OK )
165147 val = PQgetvalue (res , 0 , 0 );
166148 else
167- return get_current_timeline_from_control (FIO_DB_HOST , instance_config .pgdata , false );
149+ return get_current_timeline_from_control (FIO_DB_HOST , instance_config .pgdata );
168150
169151 if (!parse_uint32 (val , & tli , 0 ))
170152 {
171153 PQclear (res );
172154 elog (WARNING , "Invalid value of timeline_id %s" , val );
173155
174156 /* TODO 3.0 remove it and just error out */
175- return get_current_timeline_from_control (FIO_DB_HOST , instance_config .pgdata , false );
157+ return get_current_timeline_from_control (FIO_DB_HOST , instance_config .pgdata );
176158 }
177159
178160 return tli ;
179161}
180162
163+ static err_i
164+ get_control_file (fio_location location , path_t pgdata_path , path_t file ,
165+ ControlFileData * control , bool safe )
166+ {
167+ pioDrive_i drive ;
168+ char fullpath [MAXPGPATH ];
169+ ft_bytes_t bytes ;
170+ err_i err ;
171+
172+ fobj_reset_err (& err );
173+
174+ join_path_components (fullpath , pgdata_path , file );
175+
176+ drive = pioDriveForLocation (location );
177+ bytes = $i (pioReadFile , drive , .path = fullpath , .err = & err );
178+ if ($haserr (err ) && safe )
179+ {
180+ ft_logerr (FT_WARNING , $errmsg (err ), "Could not get control file" );
181+ memset (control , 0 , sizeof (ControlFileData ));
182+ return $noerr ();
183+ }
184+ if ($haserr (err ))
185+ return $err (RT , "Could not get control file: {cause}" ,
186+ cause (err .self ));
187+
188+ if (bytes .len != PG_CONTROL_FILE_SIZE )
189+ return $err (RT , "unexpected control file size: {size}, expected {wantedSz}" ,
190+ size (bytes .len ), wantedSz (PG_CONTROL_FILE_SIZE ));
191+
192+ memcpy (control , bytes .ptr , sizeof (ControlFileData ));
193+ ft_bytes_free (& bytes );
194+
195+ /* Additional checks on control file */
196+ checkControlFile (control );
197+
198+ return $noerr ();
199+ }
200+
181201/* Get timeline from pg_control file */
182202TimeLineID
183- get_current_timeline_from_control (fio_location location , const char * pgdata_path , bool safe )
203+ get_current_timeline_from_control (fio_location location , const char * pgdata_path )
184204{
205+ FOBJ_FUNC_ARP ();
185206 ControlFileData ControlFile ;
186- char * buffer ;
187- size_t size ;
207+ err_i err ;
188208
189- /* First fetch file... */
190- buffer = slurpFile (location , pgdata_path , XLOG_CONTROL_FILE ,
191- & size , safe );
192- if (safe && buffer == NULL )
193- return 0 ;
194-
195- digestControlFile (& ControlFile , buffer , size );
196- pg_free (buffer );
209+ err = get_control_file (location , pgdata_path , XLOG_CONTROL_FILE ,
210+ & ControlFile , false);
211+ if ($haserr (err ))
212+ ft_logerr (FT_FATAL , $errmsg (err ), "Getting current timeline" );
197213
198214 return ControlFile .checkPointCopy .ThisTimeLineID ;
199215}
@@ -223,16 +239,14 @@ get_checkpoint_location(PGconn *conn)
223239uint64
224240get_system_identifier (fio_location location , const char * pgdata_path , bool safe )
225241{
242+ FOBJ_FUNC_ARP ();
226243 ControlFileData ControlFile ;
227- char * buffer ;
228- size_t size ;
244+ err_i err ;
229245
230- /* First fetch file... */
231- buffer = slurpFile (location , pgdata_path , XLOG_CONTROL_FILE , & size , safe );
232- if (safe && buffer == NULL )
233- return 0 ;
234- digestControlFile (& ControlFile , buffer , size );
235- pg_free (buffer );
246+ err = get_control_file (location , pgdata_path , XLOG_CONTROL_FILE ,
247+ & ControlFile , safe );
248+ if ($haserr (err ))
249+ ft_logerr (FT_FATAL , $errmsg (err ), "Getting system identifier" );
236250
237251 return ControlFile .system_identifier ;
238252}
@@ -262,67 +276,47 @@ uint32
262276get_xlog_seg_size (const char * pgdata_path )
263277{
264278#if PG_VERSION_NUM >= 110000
279+ FOBJ_FUNC_ARP ();
265280 ControlFileData ControlFile ;
266- char * buffer ;
267- size_t size ;
281+ err_i err ;
268282
269- /* First fetch file... */
270- buffer = slurpFile ( FIO_DB_HOST , pgdata_path , XLOG_CONTROL_FILE , & size , false);
271- digestControlFile ( & ControlFile , buffer , size );
272- pg_free ( buffer );
283+ err = get_control_file ( FIO_DB_HOST , pgdata_path , XLOG_CONTROL_FILE ,
284+ & ControlFile , false);
285+ if ( $haserr ( err ))
286+ ft_logerr ( FT_FATAL , $errmsg ( err ), "Trying to fetch segment size" );
273287
274288 return ControlFile .xlog_seg_size ;
275289#else
276290 return (uint32 ) XLOG_SEG_SIZE ;
277291#endif
278292}
279293
280- uint32
281- get_data_checksum_version (bool safe )
282- {
283- ControlFileData ControlFile ;
284- char * buffer ;
285- size_t size ;
286-
287- /* First fetch file... */
288- buffer = slurpFile (FIO_DB_HOST , instance_config .pgdata , XLOG_CONTROL_FILE ,
289- & size , safe );
290- if (buffer == NULL )
291- return 0 ;
292- digestControlFile (& ControlFile , buffer , size );
293- pg_free (buffer );
294-
295- return ControlFile .data_checksum_version ;
296- }
297-
298294pg_crc32c
299295get_pgcontrol_checksum (const char * pgdata_path )
300296{
297+ FOBJ_FUNC_ARP ();
301298 ControlFileData ControlFile ;
302- char * buffer ;
303- size_t size ;
299+ err_i err ;
304300
305- /* First fetch file... */
306- buffer = slurpFile (FIO_BACKUP_HOST , pgdata_path , XLOG_CONTROL_FILE , & size , false);
307- elog (WARNING , "checking %s" , pgdata_path );
308- digestControlFile (& ControlFile , buffer , size );
309- pg_free (buffer );
301+ err = get_control_file (FIO_BACKUP_HOST , pgdata_path , XLOG_CONTROL_FILE ,
302+ & ControlFile , false);
303+ if ($haserr (err ))
304+ ft_logerr (FT_FATAL , $errmsg (err ), "Getting pgcontrol checksum" );
310305
311306 return ControlFile .crc ;
312307}
313308
314309void
315310get_redo (fio_location location , const char * pgdata_path , RedoParams * redo )
316311{
312+ FOBJ_FUNC_ARP ();
317313 ControlFileData ControlFile ;
318- char * buffer ;
319- size_t size ;
320-
321- /* First fetch file... */
322- buffer = slurpFile (location , pgdata_path , XLOG_CONTROL_FILE , & size , false);
314+ err_i err ;
323315
324- digestControlFile (& ControlFile , buffer , size );
325- pg_free (buffer );
316+ err = get_control_file (location , pgdata_path , XLOG_CONTROL_FILE ,
317+ & ControlFile , false);
318+ if ($haserr (err ))
319+ ft_logerr (FT_FATAL , $errmsg (err ), "Fetching redo lsn" );
326320
327321 redo -> lsn = ControlFile .checkPointCopy .redo ;
328322 redo -> tli = ControlFile .checkPointCopy .ThisTimeLineID ;
@@ -352,14 +346,15 @@ void
352346set_min_recovery_point (pgFile * file , const char * backup_path ,
353347 XLogRecPtr stop_backup_lsn )
354348{
349+ FOBJ_FUNC_ARP ();
355350 ControlFileData ControlFile ;
356- char * buffer ;
357- size_t size ;
358- char fullpath [MAXPGPATH ];
351+ char fullpath [MAXPGPATH ];
352+ err_i err ;
359353
360- /* First fetch file content */
361- buffer = slurpFile (FIO_DB_HOST , instance_config .pgdata , XLOG_CONTROL_FILE , & size , false);
362- digestControlFile (& ControlFile , buffer , size );
354+ err = get_control_file (FIO_DB_HOST , instance_config .pgdata , XLOG_CONTROL_FILE ,
355+ & ControlFile , false);
356+ if ($haserr (err ))
357+ ft_logerr (FT_FATAL , $errmsg (err ), "Set min recovery point" );
363358
364359 elog (LOG , "Current minRecPoint %X/%X" ,
365360 (uint32 ) (ControlFile .minRecoveryPoint >> 32 ),
@@ -383,8 +378,6 @@ set_min_recovery_point(pgFile *file, const char *backup_path,
383378
384379 /* Update pg_control checksum in backup_list */
385380 file -> crc = ControlFile .crc ;
386-
387- pg_free (buffer );
388381}
389382
390383/*
@@ -394,22 +387,21 @@ void
394387copy_pgcontrol_file (fio_location from_location , const char * from_fullpath ,
395388 fio_location to_location , const char * to_fullpath , pgFile * file )
396389{
390+ FOBJ_FUNC_ARP ();
397391 ControlFileData ControlFile ;
398- char * buffer ;
399- size_t size ;
392+ err_i err ;
400393
401- buffer = slurpFile (from_location , from_fullpath , "" , & size , false);
402-
403- digestControlFile (& ControlFile , buffer , size );
394+ err = get_control_file (from_location , from_fullpath , "" ,
395+ & ControlFile , false);
396+ if ($haserr (err ))
397+ ft_logerr (FT_FATAL , $errmsg (err ), "Fetching control file" );
404398
405399 file -> crc = ControlFile .crc ;
406- file -> read_size = ( int64_t ) size ;
407- file -> write_size = ( int64_t ) size ;
408- file -> uncompressed_size = ( int64_t ) size ;
400+ file -> read_size = PG_CONTROL_FILE_SIZE ;
401+ file -> write_size = PG_CONTROL_FILE_SIZE ;
402+ file -> uncompressed_size = PG_CONTROL_FILE_SIZE ;
409403
410404 writeControlFile (to_location , to_fullpath , & ControlFile );
411-
412- pg_free (buffer );
413405}
414406
415407/*
0 commit comments