@@ -14,6 +14,7 @@ static __thread void* fio_stdin_buffer;
14
14
static __thread int fio_stdout = 0 ;
15
15
static __thread int fio_stdin = 0 ;
16
16
static __thread int fio_stderr = 0 ;
17
+ static char * async_errormsg = NULL ;
17
18
18
19
fio_location MyLocation ;
19
20
@@ -420,6 +421,7 @@ int fio_open(char const* path, int mode, fio_location location)
420
421
IO_CHECK (fio_write_all (fio_stdout , & hdr , sizeof (hdr )), sizeof (hdr ));
421
422
IO_CHECK (fio_write_all (fio_stdout , path , hdr .size ), hdr .size );
422
423
424
+ /* check results */
423
425
IO_CHECK (fio_read_all (fio_stdin , & hdr , sizeof (hdr )), sizeof (hdr ));
424
426
425
427
if (hdr .arg != 0 )
@@ -653,6 +655,7 @@ int fio_fseek(FILE* f, off_t offs)
653
655
}
654
656
655
657
/* Set position in file */
658
+ /* TODO: make it synchronous or check async error */
656
659
int fio_seek (int fd , off_t offs )
657
660
{
658
661
if (fio_is_remote_fd (fd ))
@@ -676,20 +679,81 @@ int fio_seek(int fd, off_t offs)
676
679
677
680
/* Write data to stdio file */
678
681
size_t fio_fwrite (FILE * f , void const * buf , size_t size )
682
+ {
683
+ if (fio_is_remote_file (f ))
684
+ return fio_write (fio_fileno (f ), buf , size )
685
+ else
686
+ return fwrite (buf , 1 , size , f );
687
+ }
688
+
689
+ /* Write data to the file synchronously */
690
+ ssize_t fio_write (int fd , void const * buf , size_t size )
691
+ {
692
+ if (fio_is_remote_fd (fd ))
693
+ {
694
+ fio_header hdr ;
695
+
696
+ hdr .cop = FIO_WRITE ;
697
+ hdr .handle = fd & ~FIO_PIPE_MARKER ;
698
+ hdr .size = size ;
699
+
700
+ IO_CHECK (fio_write_all (fio_stdout , & hdr , sizeof (hdr )), sizeof (hdr ));
701
+ IO_CHECK (fio_write_all (fio_stdout , buf , size ), size );
702
+
703
+ /* check results */
704
+ IO_CHECK (fio_read_all (fio_stdin , & hdr , sizeof (hdr )), sizeof (hdr ));
705
+
706
+ /* set errno */
707
+ if (hdr .arg > 0 )
708
+ {
709
+ errno = hdr .arg ;
710
+ return -1 ;
711
+ }
712
+
713
+ return size ;
714
+ }
715
+ else
716
+ {
717
+ return write (fd , buf , size );
718
+ }
719
+ }
720
+
721
+ static void
722
+ fio_write_impl (int fd , void const * buf , size_t size , int out )
723
+ {
724
+ int rc ;
725
+ fio_header hdr ;
726
+
727
+ rc = write (fd , buf , size );
728
+
729
+ hdr .arg = 0 ;
730
+ hdr .size = 0 ;
731
+
732
+ if (rc < 0 )
733
+ hdr .arg = errno ;
734
+
735
+ /* send header */
736
+ IO_CHECK (fio_write_all (out , & hdr , sizeof (hdr )), sizeof (hdr ));
737
+
738
+ return ;
739
+ }
740
+
741
+ size_t fio_fwrite_async (FILE * f , void const * buf , size_t size )
679
742
{
680
743
return fio_is_remote_file (f )
681
- ? fio_write (fio_fileno (f ), buf , size )
744
+ ? fio_write_async (fio_fileno (f ), buf , size )
682
745
: fwrite (buf , 1 , size , f );
683
746
}
684
747
685
748
/* Write data to the file */
686
- ssize_t fio_write (int fd , void const * buf , size_t size )
749
+ /* TODO: support async report error */
750
+ ssize_t fio_write_async (int fd , void const * buf , size_t size )
687
751
{
688
752
if (fio_is_remote_fd (fd ))
689
753
{
690
754
fio_header hdr ;
691
755
692
- hdr .cop = FIO_WRITE ;
756
+ hdr .cop = FIO_WRITE_ASYNC ;
693
757
hdr .handle = fd & ~FIO_PIPE_MARKER ;
694
758
hdr .size = size ;
695
759
@@ -704,6 +768,25 @@ ssize_t fio_write(int fd, void const* buf, size_t size)
704
768
}
705
769
}
706
770
771
+ static void
772
+ fio_write_async_impl (int fd , void const * buf , size_t size , int out )
773
+ {
774
+ int rc ;
775
+
776
+ /* Quick exit for tainted agent */
777
+ if (async_errormsg )
778
+ return ;
779
+
780
+ rc = write (fd , buf , size );
781
+
782
+ if (rc <= 0 )
783
+ {
784
+ async_errormsg = pgut_malloc (ERRMSG_MAX_LEN );
785
+ snprintf (async_errormsg , ERRMSG_MAX_LEN , "%s" , strerror (errno ));
786
+ }
787
+ return ;
788
+ }
789
+
707
790
int32
708
791
fio_decompress (void * dst , void const * src , size_t size , int compress_alg )
709
792
{
@@ -727,14 +810,40 @@ fio_decompress(void* dst, void const* src, size_t size, int compress_alg)
727
810
return uncompressed_size ;
728
811
}
729
812
813
+ int32
814
+ fio_decompress_new (void * dst , void const * src , size_t size , int compress_alg , char * * errormsg )
815
+ {
816
+ const char * internal_errormsg = NULL ;
817
+ int32 uncompressed_size = do_decompress (dst , BLCKSZ ,
818
+ src ,
819
+ size ,
820
+ compress_alg , & internal_errormsg );
821
+ if (uncompressed_size < 0 && internal_errormsg != NULL )
822
+ {
823
+ elog (WARNING , "An error occured during decompressing block: %s" , internal_errormsg );
824
+ return -1 ;
825
+ }
826
+
827
+ // async_errormsg = pgut_malloc(ERRMSG_MAX_LEN);
828
+ // snprintf(async_errormsg, ERRMSG_MAX_LEN, "%s", strerror(errno));
829
+
830
+ if (uncompressed_size != BLCKSZ )
831
+ {
832
+ elog (ERROR , "Page uncompressed to %d bytes != BLCKSZ" ,
833
+ uncompressed_size );
834
+ return -1 ;
835
+ }
836
+ return uncompressed_size ;
837
+ }
838
+
730
839
/* Write data to the file */
731
- ssize_t fio_fwrite_compressed (FILE * f , void const * buf , size_t size , int compress_alg )
840
+ ssize_t fio_fwrite_async_compressed (FILE * f , void const * buf , size_t size , int compress_alg )
732
841
{
733
842
if (fio_is_remote_file (f ))
734
843
{
735
844
fio_header hdr ;
736
845
737
- hdr .cop = FIO_WRITE_COMPRESSED ;
846
+ hdr .cop = FIO_WRITE_COMPRESSED_ASYNC ;
738
847
hdr .handle = fio_fileno (f ) & ~FIO_PIPE_MARKER ;
739
848
hdr .size = size ;
740
849
hdr .arg = compress_alg ;
@@ -755,12 +864,88 @@ ssize_t fio_fwrite_compressed(FILE* f, void const* buf, size_t size, int compres
755
864
}
756
865
}
757
866
758
- static ssize_t
867
+ static void
759
868
fio_write_compressed_impl (int fd , void const * buf , size_t size , int compress_alg )
760
869
{
870
+ int rc ;
871
+ int32 uncompressed_size ;
761
872
char uncompressed_buf [BLCKSZ ];
762
- int32 uncompressed_size = fio_decompress (uncompressed_buf , buf , size , compress_alg );
763
- return fio_write_all (fd , uncompressed_buf , uncompressed_size );
873
+ char decompress_msg [128 ];
874
+
875
+ /* If the previous command already have failed,
876
+ * then there is no point in bashing a head against the wall
877
+ */
878
+ if (async_errormsg )
879
+ return ;
880
+
881
+ /* TODO: We cannot allow error out in fio_decompress */
882
+ uncompressed_size = fio_decompress (uncompressed_buf , buf , size , compress_alg );
883
+
884
+ rc = write (fd , uncompressed_buf , uncompressed_size );
885
+
886
+ if (rc <= 0 )
887
+ {
888
+ async_errormsg = pgut_malloc (ERRMSG_MAX_LEN );
889
+ snprintf (async_errormsg , ERRMSG_MAX_LEN , "%s" , strerror (errno ));
890
+ }
891
+ return ;
892
+ }
893
+
894
+ /* check if remote agent encountered any error during execution of async operations */
895
+ void
896
+ fio_check_async_error (FILE * f , const char * filepath )
897
+ {
898
+ if (fio_is_remote_file (f ))
899
+ {
900
+ char * errmsg ;
901
+ fio_header hdr ;
902
+
903
+ hdr .cop = FIO_GET_ASYNC_ERROR ;
904
+ hdr .size = 0 ;
905
+
906
+ IO_CHECK (fio_write_all (fio_stdout , & hdr , sizeof (hdr )), sizeof (hdr ));
907
+
908
+ /* check results */
909
+ IO_CHECK (fio_read_all (fio_stdin , & hdr , sizeof (hdr )), sizeof (hdr ));
910
+
911
+ if (hdr .size > 0 )
912
+ {
913
+ * errmsg = pgut_malloc (ERRMSG_MAX_LEN );
914
+ IO_CHECK (fio_read_all (fio_stdin , * errmsg , hdr .size ), hdr .size );
915
+ elog (ERROR , "Cannot write to the file \"%s\": %s" , filepath , errmsg );
916
+ }
917
+ }
918
+ }
919
+
920
+ static void
921
+ fio_get_async_error_impl (int out )
922
+ {
923
+ fio_header hdr ;
924
+
925
+ hdr .cop = FIO_GET_ASYNC_ERROR ;
926
+
927
+ /* send error message */
928
+ if (async_errormsg )
929
+ {
930
+ hdr .size = strlen (async_errormsg ) + 1 ;
931
+
932
+ /* send header */
933
+ IO_CHECK (fio_write_all (out , & hdr , sizeof (hdr )), sizeof (hdr ));
934
+
935
+ /* send message itself */
936
+ IO_CHECK (fio_write_all (out , async_errormsg , hdr .size ), hdr .size );
937
+
938
+ pg_free (async_errormsg );
939
+ async_errormsg = NULL ;
940
+ }
941
+ else
942
+ {
943
+ hdr .size = 0 ;
944
+ /* send header */
945
+ IO_CHECK (fio_write_all (out , & hdr , sizeof (hdr )), sizeof (hdr ));
946
+ }
947
+
948
+ return ;
764
949
}
765
950
766
951
/* Read data from stdio file */
@@ -2597,10 +2782,15 @@ void fio_communicate(int in, int out)
2597
2782
SYS_CHECK (close (fd [hdr .handle ]));
2598
2783
break ;
2599
2784
case FIO_WRITE : /* Write to the current position in file */
2600
- IO_CHECK (fio_write_all (fd [hdr .handle ], buf , hdr .size ), hdr .size );
2785
+ // IO_CHECK(fio_write_all(fd[hdr.handle], buf, hdr.size), hdr.size);
2786
+ fio_write_impl (fd [hdr .handle ], buf , hdr .size , out );
2601
2787
break ;
2602
- case FIO_WRITE_COMPRESSED : /* Write to the current position in file */
2603
- IO_CHECK (fio_write_compressed_impl (fd [hdr .handle ], buf , hdr .size , hdr .arg ), BLCKSZ );
2788
+ case FIO_WRITE_ASYNC : /* Write to the current position in file */
2789
+ fio_write_impl (fd [hdr .handle ], buf , hdr .size , out );
2790
+ break ;
2791
+ case FIO_WRITE_COMPRESSED_ASYNC : /* Write to the current position in file */
2792
+ //IO_CHECK(fio_write_compressed_impl(fd[hdr.handle], buf, hdr.size, hdr.arg), BLCKSZ);
2793
+ fio_write_compressed_impl (fd [hdr .handle ], buf , hdr .size , hdr .arg );
2604
2794
break ;
2605
2795
case FIO_READ : /* Read from the current position in file */
2606
2796
if ((size_t )hdr .arg > buf_size ) {
@@ -2716,6 +2906,9 @@ void fio_communicate(int in, int out)
2716
2906
hdr .cop = FIO_DISCONNECTED ;
2717
2907
IO_CHECK (fio_write_all (out , & hdr , sizeof (hdr )), sizeof (hdr ));
2718
2908
break ;
2909
+ case FIO_GET_ASYNC_ERROR :
2910
+ fio_get_async_error_impl (out );
2911
+ break ;
2719
2912
default :
2720
2913
Assert (false);
2721
2914
}
0 commit comments