@@ -714,6 +714,23 @@ zhack_repair_read_label(const int fd, vdev_label_t *vl,
714
714
return (0 );
715
715
}
716
716
717
+ static int
718
+ zhack_repair_get_byteswap (const zio_eck_t * vdev_eck , const int l , int * byteswap )
719
+ {
720
+ if (vdev_eck -> zec_magic == ZEC_MAGIC ) {
721
+ * byteswap = B_FALSE ;
722
+ } else if (vdev_eck -> zec_magic == BSWAP_64 ((uint64_t )ZEC_MAGIC )) {
723
+ * byteswap = B_TRUE ;
724
+ } else {
725
+ (void ) fprintf (stderr , "error: label %d: "
726
+ "Expected the nvlist checksum magic number but instead got "
727
+ "0x%" PRIx64 "\n" ,
728
+ l , vdev_eck -> zec_magic );
729
+ return (1 );
730
+ }
731
+ return (0 );
732
+ }
733
+
717
734
static void
718
735
zhack_repair_calc_cksum (const int byteswap , void * data , const uint64_t offset ,
719
736
const uint64_t abdsize , zio_eck_t * eck , zio_cksum_t * cksum )
@@ -740,33 +757,10 @@ zhack_repair_calc_cksum(const int byteswap, void *data, const uint64_t offset,
740
757
}
741
758
742
759
static int
743
- zhack_repair_check_label (uberblock_t * ub , const int l , const char * * cfg_keys ,
744
- const size_t cfg_keys_len , nvlist_t * cfg , nvlist_t * vdev_tree_cfg ,
745
- uint64_t * ashift )
760
+ zhack_repair_get_ashift (nvlist_t * cfg , const int l , uint64_t * ashift )
746
761
{
747
762
int err ;
748
-
749
- if (ub -> ub_txg != 0 ) {
750
- (void ) fprintf (stderr ,
751
- "error: label %d: UB TXG of 0 expected, but got %"
752
- PRIu64 "\n" ,
753
- l , ub -> ub_txg );
754
- (void ) fprintf (stderr , "It would appear the device was not "
755
- "properly removed.\n" );
756
- return (1 );
757
- }
758
-
759
- for (int i = 0 ; i < cfg_keys_len ; i ++ ) {
760
- uint64_t val ;
761
- err = nvlist_lookup_uint64 (cfg , cfg_keys [i ], & val );
762
- if (err ) {
763
- (void ) fprintf (stderr ,
764
- "error: label %d, %d: "
765
- "cannot find nvlist key %s\n" ,
766
- l , i , cfg_keys [i ]);
767
- return (err );
768
- }
769
- }
763
+ nvlist_t * vdev_tree_cfg ;
770
764
771
765
err = nvlist_lookup_nvlist (cfg ,
772
766
ZPOOL_CONFIG_VDEV_TREE , & vdev_tree_cfg );
@@ -790,7 +784,7 @@ zhack_repair_check_label(uberblock_t *ub, const int l, const char **cfg_keys,
790
784
(void ) fprintf (stderr ,
791
785
"error: label %d: nvlist key %s is zero\n" ,
792
786
l , ZPOOL_CONFIG_ASHIFT );
793
- return (err );
787
+ return (1 );
794
788
}
795
789
796
790
return (0 );
@@ -805,30 +799,35 @@ zhack_repair_undetach(uberblock_t *ub, nvlist_t *cfg, const int l)
805
799
*/
806
800
if (BP_GET_LOGICAL_BIRTH (& ub -> ub_rootbp ) != 0 ) {
807
801
const uint64_t txg = BP_GET_LOGICAL_BIRTH (& ub -> ub_rootbp );
802
+ int err ;
803
+
808
804
ub -> ub_txg = txg ;
809
805
810
- if (nvlist_remove_all (cfg , ZPOOL_CONFIG_CREATE_TXG ) != 0 ) {
806
+ err = nvlist_remove_all (cfg , ZPOOL_CONFIG_CREATE_TXG );
807
+ if (err ) {
811
808
(void ) fprintf (stderr ,
812
809
"error: label %d: "
813
810
"Failed to remove pool creation TXG\n" ,
814
811
l );
815
- return (1 );
812
+ return (err );
816
813
}
817
814
818
- if (nvlist_remove_all (cfg , ZPOOL_CONFIG_POOL_TXG ) != 0 ) {
815
+ err = nvlist_remove_all (cfg , ZPOOL_CONFIG_POOL_TXG );
816
+ if (err ) {
819
817
(void ) fprintf (stderr ,
820
818
"error: label %d: Failed to remove pool TXG to "
821
819
"be replaced.\n" ,
822
820
l );
823
- return (1 );
821
+ return (err );
824
822
}
825
823
826
- if (nvlist_add_uint64 (cfg , ZPOOL_CONFIG_POOL_TXG , txg ) != 0 ) {
824
+ err = nvlist_add_uint64 (cfg , ZPOOL_CONFIG_POOL_TXG , txg );
825
+ if (err ) {
827
826
(void ) fprintf (stderr ,
828
827
"error: label %d: "
829
828
"Failed to add pool TXG of %" PRIu64 "\n" ,
830
829
l , txg );
831
- return (1 );
830
+ return (err );
832
831
}
833
832
}
834
833
@@ -922,6 +921,7 @@ zhack_repair_test_cksum(const int byteswap, void *vdev_data,
922
921
BSWAP_64 (ZEC_MAGIC ) : ZEC_MAGIC ;
923
922
const uint64_t actual_magic = vdev_eck -> zec_magic ;
924
923
int err = 0 ;
924
+
925
925
if (actual_magic != expected_magic ) {
926
926
(void ) fprintf (stderr , "error: label %d: "
927
927
"Expected "
@@ -943,6 +943,36 @@ zhack_repair_test_cksum(const int byteswap, void *vdev_data,
943
943
return (err );
944
944
}
945
945
946
+ static int
947
+ zhack_repair_unpack_cfg (vdev_label_t * vl , const int l , nvlist_t * * cfg )
948
+ {
949
+ const char * cfg_keys [] = { ZPOOL_CONFIG_VERSION ,
950
+ ZPOOL_CONFIG_POOL_STATE , ZPOOL_CONFIG_GUID };
951
+ int err ;
952
+
953
+ err = nvlist_unpack (vl -> vl_vdev_phys .vp_nvlist ,
954
+ VDEV_PHYS_SIZE - sizeof (zio_eck_t ), cfg , 0 );
955
+ if (err ) {
956
+ (void ) fprintf (stderr ,
957
+ "error: cannot unpack nvlist label %d\n" , l );
958
+ return (err );
959
+ }
960
+
961
+ for (int i = 0 ; i < ARRAY_SIZE (cfg_keys ); i ++ ) {
962
+ uint64_t val ;
963
+ err = nvlist_lookup_uint64 (* cfg , cfg_keys [i ], & val );
964
+ if (err ) {
965
+ (void ) fprintf (stderr ,
966
+ "error: label %d, %d: "
967
+ "cannot find nvlist key %s\n" ,
968
+ l , i , cfg_keys [i ]);
969
+ return (err );
970
+ }
971
+ }
972
+
973
+ return (0 );
974
+ }
975
+
946
976
static void
947
977
zhack_repair_one_label (const zhack_repair_op_t op , const int fd ,
948
978
vdev_label_t * vl , const uint64_t label_offset , const int l ,
@@ -956,29 +986,17 @@ zhack_repair_one_label(const zhack_repair_op_t op, const int fd,
956
986
(zio_eck_t * )((char * )(vdev_data ) + VDEV_PHYS_SIZE ) - 1 ;
957
987
const uint64_t vdev_phys_offset =
958
988
label_offset + offsetof(vdev_label_t , vl_vdev_phys );
959
- const char * cfg_keys [] = { ZPOOL_CONFIG_VERSION ,
960
- ZPOOL_CONFIG_POOL_STATE , ZPOOL_CONFIG_GUID };
961
989
nvlist_t * cfg ;
962
- nvlist_t * vdev_tree_cfg = NULL ;
963
990
uint64_t ashift ;
964
991
int byteswap ;
965
992
966
993
err = zhack_repair_read_label (fd , vl , label_offset , l );
967
994
if (err )
968
995
return ;
969
996
970
- if (vdev_eck -> zec_magic == 0 ) {
971
- (void ) fprintf (stderr , "error: label %d: "
972
- "Expected the nvlist checksum magic number to not be zero"
973
- "\n" ,
974
- l );
975
- (void ) fprintf (stderr , "There should already be a checksum "
976
- "for the label.\n" );
997
+ err = zhack_repair_get_byteswap (vdev_eck , l , & byteswap );
998
+ if (err )
977
999
return ;
978
- }
979
-
980
- byteswap =
981
- (vdev_eck -> zec_magic == BSWAP_64 ((uint64_t )ZEC_MAGIC ));
982
1000
983
1001
if (byteswap ) {
984
1002
byteswap_uint64_array (& vdev_eck -> zec_cksum ,
@@ -994,23 +1012,28 @@ zhack_repair_one_label(const zhack_repair_op_t op, const int fd,
994
1012
return ;
995
1013
}
996
1014
997
- err = nvlist_unpack (vl -> vl_vdev_phys .vp_nvlist ,
998
- VDEV_PHYS_SIZE - sizeof (zio_eck_t ), & cfg , 0 );
999
- if (err ) {
1000
- (void ) fprintf (stderr ,
1001
- "error: cannot unpack nvlist label %d\n" , l );
1002
- return ;
1003
- }
1004
-
1005
- err = zhack_repair_check_label (ub ,
1006
- l , cfg_keys , ARRAY_SIZE (cfg_keys ), cfg , vdev_tree_cfg , & ashift );
1015
+ err = zhack_repair_unpack_cfg (vl , l , & cfg );
1007
1016
if (err )
1008
1017
return ;
1009
1018
1010
1019
if ((op & ZHACK_REPAIR_OP_UNDETACH ) != 0 ) {
1011
1020
char * buf ;
1012
1021
size_t buflen ;
1013
1022
1023
+ if (ub -> ub_txg != 0 ) {
1024
+ (void ) fprintf (stderr ,
1025
+ "error: label %d: UB TXG of 0 expected, but got %"
1026
+ PRIu64 "\n" ,
1027
+ l , ub -> ub_txg );
1028
+ (void ) fprintf (stderr , "It would appear the device was "
1029
+ "not properly detached.\n" );
1030
+ return ;
1031
+ }
1032
+
1033
+ err = zhack_repair_get_ashift (cfg , l , & ashift );
1034
+ if (err )
1035
+ return ;
1036
+
1014
1037
err = zhack_repair_undetach (ub , cfg , l );
1015
1038
if (err )
1016
1039
return ;
0 commit comments