diff --git a/include/zrepl_mgmt.h b/include/zrepl_mgmt.h index 6feb4537cf07..535157b0f55b 100644 --- a/include/zrepl_mgmt.h +++ b/include/zrepl_mgmt.h @@ -246,6 +246,9 @@ int uzfs_zvol_destroy_snapshot_clone(zvol_state_t *zv, zvol_state_t *snap_zv, zvol_state_t *clone_zv); int uzfs_zinfo_destroy_internal_clone(zvol_info_t *zv); +uint8_t uzfs_zinfo_get_quorum(zvol_info_t *zinfo); +int uzfs_zinfo_set_quorum(zvol_info_t *zinfo, uint64_t val); + /* * API to drop refcnt on zinfo. If refcnt * dropped to zero then free zinfo. diff --git a/include/zrepl_prot.h b/include/zrepl_prot.h index 1044a1cbfee5..766b1f813bc7 100644 --- a/include/zrepl_prot.h +++ b/include/zrepl_prot.h @@ -45,7 +45,7 @@ extern "C" { * properly aligned (and packed). */ -#define REPLICA_VERSION 2 +#define REPLICA_VERSION 3 #define MAX_NAME_LEN 256 #define MAX_IP_LEN 64 #define TARGET_PORT 6060 @@ -134,6 +134,8 @@ struct mgmt_ack { uint64_t pool_guid; uint64_t zvol_guid; uint16_t port; + uint8_t quorum; + uint8_t reserved[5]; char ip[MAX_IP_LEN]; char volname[MAX_NAME_LEN]; // zvol helping rebuild char dw_volname[MAX_NAME_LEN]; // zvol being rebuilt diff --git a/lib/libzpool/zrepl_mgmt.c b/lib/libzpool/zrepl_mgmt.c index 14a30394043b..fcdf1cff1243 100644 --- a/lib/libzpool/zrepl_mgmt.c +++ b/lib/libzpool/zrepl_mgmt.c @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include #include #include @@ -457,6 +459,25 @@ uzfs_zinfo_store_last_committed_degraded_io_no(zvol_info_t *zinfo, DEGRADED_IO_SEQNUM, io_seq); } +uint8_t +uzfs_zinfo_get_quorum(zvol_info_t *zinfo) +{ + uint64_t quorum; + VERIFY0(dsl_prop_get_integer(zinfo->main_zv->zv_name, + zfs_prop_to_name(ZFS_PROP_QUORUM), &quorum, NULL)); + return (!!quorum); +} + +int +uzfs_zinfo_set_quorum(zvol_info_t *zinfo, uint64_t val) +{ + int err = dsl_dataset_set_quorum(zinfo->main_zv->zv_name, + ZPROP_SRC_LOCAL, 1); + if (err) + return (err); + return (0); +} + /* * Stores given io_seq as healthy_io_seqnum if previously committed is * less than given io_seq. diff --git a/lib/libzrepl/data_conn.c b/lib/libzrepl/data_conn.c index 83f600c3f4bd..777b9ae99bf5 100644 --- a/lib/libzrepl/data_conn.c +++ b/lib/libzrepl/data_conn.c @@ -841,8 +841,7 @@ uzfs_zvol_rebuild_dw_replica(void *arg) * set the quorum to 1 once rebuild is done. istgt will * start considering it in the quorum decision. */ - VERIFY0(dsl_dataset_set_quorum(zinfo->main_zv->zv_name, - ZPROP_SRC_LOCAL, 1)); + VERIFY0(uzfs_zinfo_set_quorum(zinfo, 1)); mutex_enter(&zinfo->main_zv->rebuild_mtx); /* Mark replica healthy now */ diff --git a/lib/libzrepl/mgmt_conn.c b/lib/libzrepl/mgmt_conn.c index 176bac6ef075..b9d6b3c93145 100644 --- a/lib/libzrepl/mgmt_conn.c +++ b/lib/libzrepl/mgmt_conn.c @@ -513,6 +513,7 @@ uzfs_zvol_mgmt_get_handshake_info(zvol_io_hdr_t *in_hdr, const char *name, mgmt_ack->checkpointed_io_seq = zinfo->checkpointed_ionum; mgmt_ack->checkpointed_degraded_io_seq = zinfo->degraded_checkpointed_ionum; + mgmt_ack->quorum = uzfs_zinfo_get_quorum(zinfo); return (0); } diff --git a/tests/cbtest/gtest/test_uzfs.cc b/tests/cbtest/gtest/test_uzfs.cc index 8efe038de216..edc36e5663f7 100644 --- a/tests/cbtest/gtest/test_uzfs.cc +++ b/tests/cbtest/gtest/test_uzfs.cc @@ -2571,7 +2571,7 @@ void mock_tgt_thread(void *arg) /* Send wrong protocol version */ if (mgmt_test_case == 2) - hdr.version = 3; + hdr.version = -1; /* Header len is greater than MAX_NAME_LEN */ if (mgmt_test_case == 4)