From e42b8123239e758908f224d24bab271b288a878f Mon Sep 17 00:00:00 2001 From: Vitaliy Filippov Date: Sun, 5 Apr 2026 10:55:45 +0300 Subject: [PATCH] Allow to skip checksums for headers --- src/client/messenger.cpp | 19 +++++++++++++++---- src/client/messenger.h | 7 ++++--- src/client/msgr_rdma.cpp | 4 ++-- src/client/msgr_receive.cpp | 19 ++++++++++++------- src/client/msgr_send.cpp | 27 ++++++++++++++++----------- src/osd/osd_secondary.cpp | 13 ++++++++++--- 6 files changed, 59 insertions(+), 30 deletions(-) diff --git a/src/client/messenger.cpp b/src/client/messenger.cpp index 93267be5..89060393 100644 --- a/src/client/messenger.cpp +++ b/src/client/messenger.cpp @@ -340,7 +340,14 @@ void osd_messenger_t::parse_config(const json11::Json & config) this->max_aes_xts_pool_size = config["max_aes_xts_pool_size"].uint64_value(); if (!this->max_aes_xts_pool_size) this->max_aes_xts_pool_size = 256; - this->use_proto_checksums = config["use_proto_checksums"].is_null() || config["use_proto_checksums"].bool_value(); + if (config["proto_checksums"].is_null()) + this->use_proto_checksums = MSGR_CSUM_PAYLOAD; + else if (config["proto_checksums"].is_bool()) + this->use_proto_checksums = config["proto_checksums"].bool_value() ? MSGR_CSUM_FULL : 0; + else if (config["proto_checksums"].string_value() != "") + this->use_proto_checksums = config["proto_checksums"].string_value() == "full" ? MSGR_CSUM_FULL : MSGR_CSUM_PAYLOAD; + else + this->use_proto_checksums = 0; if (!osd_num) this->iothread_count = (uint32_t)config["client_iothread_count"].uint64_value(); else @@ -663,7 +670,7 @@ void osd_messenger_t::check_peer_config(osd_client_t *cl) auto features = json11::Json::object{ { "check_sequencing", true } }; if (use_proto_checksums) { - features["proto_checksums"] = true; + features["proto_checksums"] = use_proto_checksums; } payload["features"] = features; #ifdef WITH_RDMA @@ -740,9 +747,13 @@ void osd_messenger_t::check_peer_config(osd_client_t *cl) delete op; return; } - if (use_proto_checksums && config["features"]["proto_checksums"].bool_value()) + if (use_proto_checksums) { - cl->proto_csum_status = MSGR_PEER_CSUM_IN|MSGR_PEER_CSUM_OUT; + auto peer_csums = config["features"]["proto_checksums"].uint64_value(); + if (peer_csums == MSGR_CSUM_FULL && use_proto_checksums == MSGR_CSUM_FULL) + cl->proto_csum_status = MSGR_CSUM_FULL; + else if (peer_csums && use_proto_checksums) + cl->proto_csum_status = MSGR_CSUM_PAYLOAD; } #ifdef WITH_RDMA if (!use_rdmacm && cl->rdma_conn && config["rdma_address"].is_string()) diff --git a/src/client/messenger.h b/src/client/messenger.h index 97810b21..4a095b53 100644 --- a/src/client/messenger.h +++ b/src/client/messenger.h @@ -32,8 +32,9 @@ #define PEER_RDMA 4 #define PEER_STOPPED 5 -#define MSGR_PEER_CSUM_IN 1 -#define MSGR_PEER_CSUM_OUT 2 +#define MSGR_CSUM_PAYLOAD 1 +#define MSGR_CSUM_FULL 2 +#define MSGR_CSUM_NEG 4 #define VITASTOR_CONFIG_PATH "/etc/vitastor/vitastor.conf" @@ -252,7 +253,7 @@ public: std::vector osd_cluster_network_masks; std::vector all_osd_networks; std::vector all_osd_network_masks; - bool use_proto_checksums = true; + int use_proto_checksums = 0; // op statistics osd_op_stats_t stats, recovery_stats; diff --git a/src/client/msgr_rdma.cpp b/src/client/msgr_rdma.cpp index 3e1bc0b0..a9618b24 100644 --- a/src/client/msgr_rdma.cpp +++ b/src/client/msgr_rdma.cpp @@ -758,10 +758,10 @@ void osd_messenger_t::handle_rdma_events(msgr_rdma_context_t *rdma_context) cl->send_free_ops.pop_front(); } cl->send_free_ops.pop_front(); - if (cl->proto_csum_status == MSGR_PEER_CSUM_IN && !cl->write_op && !cl->write_ops.size()) + if ((cl->proto_csum_status & MSGR_CSUM_NEG) && !cl->write_op && !cl->write_ops.size()) { // Checksums negotiated, enable - cl->proto_csum_status = MSGR_PEER_CSUM_IN|MSGR_PEER_CSUM_OUT; + cl->proto_csum_status = cl->proto_csum_status & (~MSGR_CSUM_NEG); } try_send_rdma(cl); } diff --git a/src/client/msgr_receive.cpp b/src/client/msgr_receive.cpp index 0ef8b11c..71b06167 100644 --- a/src/client/msgr_receive.cpp +++ b/src/client/msgr_receive.cpp @@ -203,7 +203,7 @@ bool osd_messenger_t::handle_read_buffer(osd_client_t *cl, uint8_t *curbuf, size cl->read_op_size = 0; cl->read_op_inline_decrypt_in = 0; cl->read_op_inline_decrypt_pos = (size_t)-1; - if (cl->proto_csum_status == (MSGR_PEER_CSUM_IN|MSGR_PEER_CSUM_OUT)) + if (cl->proto_csum_status == MSGR_CSUM_FULL || cl->proto_csum_status == MSGR_CSUM_PAYLOAD) { if (!cl->read_csum_state) cl->read_csum_state = XXH3_createState(); @@ -236,7 +236,7 @@ bool osd_messenger_t::handle_read_buffer(osd_client_t *cl, uint8_t *curbuf, size bool osd_messenger_t::handle_hdr(osd_client_t *cl) { - if (cl->read_csum_state) + if (cl->proto_csum_status == MSGR_CSUM_FULL) { XXH3_64bits_update(cl->read_csum_state, cl->read_op->req.buf, OSD_PACKET_SIZE); } @@ -337,7 +337,8 @@ bool osd_messenger_t::allocate_op_buffers(osd_client_t *cl) } cl->read_op_size = cur_op->req.show_conf.json_len; } - if (cl->proto_csum_status == (MSGR_PEER_CSUM_IN|MSGR_PEER_CSUM_OUT)) + if (cl->proto_csum_status == MSGR_CSUM_FULL || + cl->read_op_size > 0 && cl->proto_csum_status == MSGR_CSUM_PAYLOAD) { cl->read_op_size += 8; } @@ -395,7 +396,8 @@ bool osd_messenger_t::allocate_reply_buffers(osd_client_t *cl, osd_op_t *op) free(op->buf); op->buf = malloc_or_die(op->reply.describe.result_bytes); } - if (cl->proto_csum_status == (MSGR_PEER_CSUM_IN|MSGR_PEER_CSUM_OUT)) + if (cl->proto_csum_status == MSGR_CSUM_FULL || + cl->read_op_size > 0 && cl->proto_csum_status == MSGR_CSUM_PAYLOAD) { cl->read_op_size += 8; } @@ -520,7 +522,8 @@ bool osd_messenger_t::op_copy_from(osd_client_t *cl, uint8_t *src, size_t src_le return true; } } - if (cl->proto_csum_status == (MSGR_PEER_CSUM_IN|MSGR_PEER_CSUM_OUT)) + if (cl->proto_csum_status == MSGR_CSUM_FULL || + cl->read_op_size > 0 && cl->proto_csum_status == MSGR_CSUM_PAYLOAD) { if (!op_read_buf((uint8_t*)&op->csum, 8, true)) return true; @@ -642,7 +645,8 @@ void osd_messenger_t::op_get_read_buffers(osd_client_t *cl, std::vector & return; } } - if (cl->proto_csum_status == (MSGR_PEER_CSUM_IN|MSGR_PEER_CSUM_OUT)) + if (cl->proto_csum_status == MSGR_CSUM_FULL || + cl->read_op_size > 0 && cl->proto_csum_status == MSGR_CSUM_PAYLOAD) { if (!op_read_buf((uint8_t*)&op->csum, 8)) return; @@ -676,7 +680,8 @@ void osd_messenger_t::op_alloc_temp_buffers(osd_op_t *op, int i) bool osd_messenger_t::handle_finished_op(osd_client_t *cl) { osd_op_t *op = cl->read_op; - if (cl->proto_csum_status == (MSGR_PEER_CSUM_IN|MSGR_PEER_CSUM_OUT)) + if (cl->proto_csum_status == MSGR_CSUM_FULL || + cl->read_op_size > 0 && cl->proto_csum_status == MSGR_CSUM_PAYLOAD) { uint64_t real_csum = XXH3_64bits_digest(cl->read_csum_state); if (op->csum != real_csum) diff --git a/src/client/msgr_send.cpp b/src/client/msgr_send.cpp index 945bfeb4..6bcea1c4 100644 --- a/src/client/msgr_send.cpp +++ b/src/client/msgr_send.cpp @@ -268,10 +268,10 @@ void osd_messenger_t::handle_send(int result, bool prev, bool more, osd_client_t cl->zc_free_list.push_back(NULL); // end marker cl->send_free_ops.clear(); cl->write_state = cl->write_op || cl->write_ops.size() ? CL_WRITE_READY : 0; - if (cl->proto_csum_status == MSGR_PEER_CSUM_IN && !cl->write_op && !cl->write_ops.size()) + if ((cl->proto_csum_status & MSGR_CSUM_NEG) && !cl->write_op && !cl->write_ops.size()) { // Checksums negotiated, enable - cl->proto_csum_status = MSGR_PEER_CSUM_IN|MSGR_PEER_CSUM_OUT; + cl->proto_csum_status = cl->proto_csum_status & (~MSGR_CSUM_NEG); } #ifdef WITH_RDMA if (cl->rdma_conn && !cl->write_op && !cl->write_ops.size() && cl->peer_state == PEER_RDMA_CONNECTING) @@ -293,11 +293,12 @@ void osd_messenger_t::handle_send(int result, bool prev, bool more, osd_client_t } } -static inline bool op_write_headers(osd_op_t *op, std::function op_write_buf) +static inline bool op_write_headers(osd_op_t *op, std::function op_write_buf, bool skip_hdr_csum) { - // Header - if (!op_write_buf((op->op_type == OSD_OP_IN ? op->reply.buf : op->req.buf), OSD_PACKET_SIZE, false)) + if (!op_write_buf((op->op_type == OSD_OP_IN ? op->reply.buf : op->req.buf), OSD_PACKET_SIZE, skip_hdr_csum)) + { return false; + } // Bitmap if (op->op_type == OSD_OP_IN && op->req.hdr.opcode == OSD_OP_SEC_READ && @@ -370,13 +371,14 @@ size_t osd_messenger_t::op_copy_to(osd_client_t *cl, uint8_t *dst, size_t dst_le from -= src_len; return true; }; - if (cl->proto_csum_status == (MSGR_PEER_CSUM_IN|MSGR_PEER_CSUM_OUT) && !from) + if ((cl->proto_csum_status == MSGR_CSUM_FULL || cl->proto_csum_status == MSGR_CSUM_PAYLOAD) && !from) { if (!cl->write_csum_state) cl->write_csum_state = XXH3_createState(); XXH3_64bits_reset(cl->write_csum_state); } - if (!op_write_headers(cl->write_op, op_write_buf)) + // Header + if (!op_write_headers(cl->write_op, op_write_buf, cl->proto_csum_status != MSGR_CSUM_FULL)) { return done; } @@ -399,7 +401,8 @@ size_t osd_messenger_t::op_copy_to(osd_client_t *cl, uint8_t *dst, size_t dst_le } } } - if (cl->write_csum_state) + if (cl->proto_csum_status == MSGR_CSUM_FULL || + cl->proto_csum_status == MSGR_CSUM_PAYLOAD && cl->write_op_pos > OSD_PACKET_SIZE) { if (!from) cl->write_op->csum = XXH3_64bits_digest(cl->write_csum_state); @@ -430,13 +433,14 @@ void osd_messenger_t::op_get_write_buffers(osd_client_t *cl, std::vector from -= src_len; return true; }; - if (cl->proto_csum_status == (MSGR_PEER_CSUM_IN|MSGR_PEER_CSUM_OUT) && !from) + if ((cl->proto_csum_status == MSGR_CSUM_FULL || cl->proto_csum_status == MSGR_CSUM_PAYLOAD) && !from) { if (!cl->write_csum_state) cl->write_csum_state = XXH3_createState(); XXH3_64bits_reset(cl->write_csum_state); } - if (!op_write_headers(cl->write_op, op_write_buf)) + // Header + if (!op_write_headers(cl->write_op, op_write_buf, cl->proto_csum_status != MSGR_CSUM_FULL)) { return; } @@ -467,7 +471,8 @@ void osd_messenger_t::op_get_write_buffers(osd_client_t *cl, std::vector } } } - if (cl->write_csum_state) + if (cl->proto_csum_status == MSGR_CSUM_FULL || + cl->proto_csum_status == MSGR_CSUM_PAYLOAD && cl->write_op_pos > OSD_PACKET_SIZE) { if (!from) cl->write_op->csum = XXH3_64bits_digest(cl->write_csum_state); diff --git a/src/osd/osd_secondary.cpp b/src/osd/osd_secondary.cpp index 937536cd..a428498f 100644 --- a/src/osd/osd_secondary.cpp +++ b/src/osd/osd_secondary.cpp @@ -348,10 +348,17 @@ void osd_t::exec_show_config(osd_op_t *cur_op) cl->read_op_id = cur_op->req.hdr.id + 1; } auto features = json11::Json::object{ { "pg_locks", true } }; - if (req_json["features"]["proto_checksums"].bool_value() && msgr.use_proto_checksums) + if (msgr.use_proto_checksums) { - cl->proto_csum_status = MSGR_PEER_CSUM_IN; - features["proto_checksums"] = true; + auto peer_csums = req_json["features"]["proto_checksums"].uint64_value(); + if (peer_csums == MSGR_CSUM_FULL || peer_csums == MSGR_CSUM_PAYLOAD) + { + if (msgr.use_proto_checksums == MSGR_CSUM_FULL && peer_csums == MSGR_CSUM_FULL) + cl->proto_csum_status = MSGR_CSUM_FULL|MSGR_CSUM_NEG; + else + cl->proto_csum_status = MSGR_CSUM_PAYLOAD|MSGR_CSUM_NEG; + features["proto_checksums"] = msgr.use_proto_checksums; + } } // Expose sensitive configuration values so peers can check them json11::Json::object wire_config = json11::Json::object {