@@ -363,6 +363,74 @@ pg_tde_delete_principal_key(Oid dbOid)
363
363
durable_unlink (path , ERROR );
364
364
}
365
365
366
+ static FILE *
367
+ pg_tde_open_file_basic_copy (const char * tde_filename , const char * mode , bool ignore_missing )
368
+ {
369
+ FILE * file ;
370
+
371
+ file = AllocateFile (tde_filename , mode );
372
+ if (file == NULL && !(errno == ENOENT && ignore_missing == true))
373
+ {
374
+ ereport (ERROR ,
375
+ errcode_for_file_access (),
376
+ errmsg ("could not open tde file \"%s\": %m" , tde_filename ));
377
+ }
378
+
379
+ return file ;
380
+ }
381
+
382
+ static void
383
+ pg_tde_file_header_read_copy (const char * tde_filename , FILE * file , TDEFileHeader * fheader )
384
+ {
385
+ size_t bytes_read ;
386
+
387
+ Assert (fheader );
388
+
389
+ bytes_read = fread (fheader , TDE_FILE_HEADER_SIZE , 1 , file );
390
+
391
+ if (bytes_read != 1 || fheader -> file_version != PG_TDE_FILEMAGIC )
392
+ {
393
+ ereport (FATAL ,
394
+ errcode_for_file_access (),
395
+ errmsg ("TDE map file \"%s\" is corrupted %ld %d: %m" , tde_filename , bytes_read , fheader -> file_version ));
396
+ }
397
+ }
398
+
399
+ static FILE *
400
+ pg_tde_open_file_write_copy (const char * tde_filename , const TDESignedPrincipalKeyInfo * signed_key_info )
401
+ {
402
+ FILE * file ;
403
+ TDEFileHeader fheader ;
404
+
405
+ Assert (LWLockHeldByMeInMode (tde_lwlock_enc_keys (), LW_EXCLUSIVE ));
406
+
407
+ file = pg_tde_open_file_basic_copy (tde_filename , "rb+" , false);
408
+
409
+ pg_tde_file_header_read_copy (tde_filename , file , & fheader );
410
+
411
+ ///* In case it's a new file, let's add the header now. */
412
+ //if (bytes_read == 0 && signed_key_info)
413
+ // pg_tde_file_header_write(tde_filename, fd, signed_key_info, &bytes_written);
414
+
415
+ return file ;
416
+ }
417
+
418
+ static bool
419
+ pg_tde_read_one_map_entry_copy (FILE * map_file , TDEMapEntry * map_entry )
420
+ {
421
+ size_t entries_read ;
422
+
423
+ Assert (map_entry );
424
+
425
+ entries_read = fread (map_entry , MAP_ENTRY_SIZE , 1 , map_file );
426
+
427
+ /* We've reached the end of the file. */
428
+ if (entries_read != 1 )
429
+ return false;
430
+
431
+ return true;
432
+ }
433
+
366
434
/*
367
435
* The caller must hold an exclusive lock on the key file to avoid
368
436
* concurrent in place updates leading to data conflicts.
371
439
pg_tde_replace_key_map_entry (const RelFileLocator * rlocator , const InternalKey * rel_key_data , TDEPrincipalKey * principal_key )
372
440
{
373
441
char db_map_path [MAXPGPATH ];
374
- int map_fd ;
375
- off_t curr_pos = 0 ;
442
+ FILE * map_file ;
376
443
off_t write_pos = 0 ;
377
444
TDEMapEntry write_map_entry ;
378
445
TDESignedPrincipalKeyInfo signed_key_Info ;
@@ -384,7 +451,7 @@ pg_tde_replace_key_map_entry(const RelFileLocator *rlocator, const InternalKey *
384
451
pg_tde_sign_principal_key_info (& signed_key_Info , principal_key );
385
452
386
453
/* Open and validate file for basic correctness. */
387
- map_fd = pg_tde_open_file_write (db_map_path , & signed_key_Info , false, & curr_pos );
454
+ map_file = pg_tde_open_file_write_copy (db_map_path , & signed_key_Info );
388
455
389
456
/*
390
457
* Read until we find an empty slot. Otherwise, read until end. This seems
@@ -394,32 +461,31 @@ pg_tde_replace_key_map_entry(const RelFileLocator *rlocator, const InternalKey *
394
461
while (1 )
395
462
{
396
463
TDEMapEntry read_map_entry ;
397
- off_t prev_pos = curr_pos ;
398
464
399
- if (!pg_tde_read_one_map_entry ( map_fd , & read_map_entry , & curr_pos ))
465
+ if (!pg_tde_read_one_map_entry_copy ( map_file , & read_map_entry ))
400
466
{
401
467
if (write_pos == 0 )
402
- write_pos = prev_pos ;
468
+ write_pos = ftell ( map_file ) ;
403
469
break ;
404
470
}
405
471
406
472
if (read_map_entry .spcOid == rlocator -> spcOid && read_map_entry .relNumber == rlocator -> relNumber )
407
473
{
408
- write_pos = prev_pos ;
474
+ write_pos = ftell ( map_file ) - MAP_ENTRY_SIZE ;
409
475
break ;
410
476
}
411
477
412
478
if (write_pos == 0 && read_map_entry .type == MAP_ENTRY_EMPTY )
413
- write_pos = prev_pos ;
479
+ write_pos = ftell ( map_file ) - MAP_ENTRY_SIZE ;
414
480
}
415
481
416
482
/* Initialize map entry and encrypt key */
417
483
pg_tde_initialize_map_entry (& write_map_entry , principal_key , rlocator , rel_key_data );
418
484
419
485
/* Write the given entry at curr_pos; i.e. the free entry. */
420
- pg_tde_write_one_map_entry (map_fd , & write_map_entry , & write_pos , db_map_path );
486
+ pg_tde_write_one_map_entry (fileno ( map_file ) , & write_map_entry , & write_pos , db_map_path );
421
487
422
- CloseTransientFile ( map_fd );
488
+ FreeFile ( map_file );
423
489
}
424
490
425
491
#endif /* !FRONTEND */
0 commit comments