From: Amitay Isaacs Date: Thu, 29 Jun 2017 14:36:18 +0000 (+1000) Subject: ctdb-protocol: Fix marshalling for ctdb_tunable X-Git-Tag: ldb-1.2.2~112 X-Git-Url: http://git.samba.org/samba.git/?p=vlendec%2Fsamba-autobuild%2F.git;a=commitdiff_plain;h=60cb067885fff2410a66649318be1f8723f38668 ctdb-protocol: Fix marshalling for ctdb_tunable Signed-off-by: Amitay Isaacs Reviewed-by: Martin Schwenke --- diff --git a/ctdb/protocol/protocol_control.c b/ctdb/protocol/protocol_control.c index 057dc25719a..61e0d7c5175 100644 --- a/ctdb/protocol/protocol_control.c +++ b/ctdb/protocol/protocol_control.c @@ -523,7 +523,7 @@ static void ctdb_req_control_data_push(struct ctdb_req_control_data *cd, break; case CTDB_CONTROL_SET_TUNABLE: - ctdb_tunable_push(cd->data.tunable, buf); + ctdb_tunable_push(cd->data.tunable, buf, &np); break; case CTDB_CONTROL_GET_TUNABLE: @@ -818,7 +818,7 @@ static int ctdb_req_control_data_pull(uint8_t *buf, size_t buflen, case CTDB_CONTROL_SET_TUNABLE: ret = ctdb_tunable_pull(buf, buflen, mem_ctx, - &cd->data.tunable); + &cd->data.tunable, &np); break; case CTDB_CONTROL_GET_TUNABLE: diff --git a/ctdb/protocol/protocol_private.h b/ctdb/protocol/protocol_private.h index a198be9d55a..716ddd61d81 100644 --- a/ctdb/protocol/protocol_private.h +++ b/ctdb/protocol/protocol_private.h @@ -186,10 +186,10 @@ void ctdb_connection_push(struct ctdb_connection *in, uint8_t *buf, int ctdb_connection_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx, struct ctdb_connection **out, size_t *npull); -size_t ctdb_tunable_len(struct ctdb_tunable *tunable); -void ctdb_tunable_push(struct ctdb_tunable *tunable, uint8_t *buf); +size_t ctdb_tunable_len(struct ctdb_tunable *in); +void ctdb_tunable_push(struct ctdb_tunable *in, uint8_t *buf, size_t *npush); int ctdb_tunable_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx, - struct ctdb_tunable **out); + struct ctdb_tunable **out, size_t *npull); size_t ctdb_node_flag_change_len(struct ctdb_node_flag_change *flag_change); void ctdb_node_flag_change_push(struct ctdb_node_flag_change *flag_change, diff --git a/ctdb/protocol/protocol_types.c b/ctdb/protocol/protocol_types.c index 7e3fb75db6e..c32d4efded4 100644 --- a/ctdb/protocol/protocol_types.c +++ b/ctdb/protocol/protocol_types.c @@ -2150,61 +2150,57 @@ int ctdb_connection_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx, return ret; } -struct ctdb_tunable_wire { - uint32_t value; - uint32_t length; - uint8_t name[1]; -}; - -size_t ctdb_tunable_len(struct ctdb_tunable *tunable) +size_t ctdb_tunable_len(struct ctdb_tunable *in) { - return offsetof(struct ctdb_tunable_wire, name) + - strlen(tunable->name) + 1; + return ctdb_uint32_len(&in->value) + + ctdb_stringn_len(&in->name); } -void ctdb_tunable_push(struct ctdb_tunable *tunable, uint8_t *buf) +void ctdb_tunable_push(struct ctdb_tunable *in, uint8_t *buf, size_t *npush) { - struct ctdb_tunable_wire *wire = (struct ctdb_tunable_wire *)buf; + size_t offset = 0, np; - wire->value = tunable->value; - wire->length = strlen(tunable->name) + 1; - memcpy(wire->name, tunable->name, wire->length); + ctdb_uint32_push(&in->value, buf+offset, &np); + offset += np; + + ctdb_stringn_push(&in->name, buf+offset, &np); + offset += np; + + *npush = offset; } int ctdb_tunable_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx, - struct ctdb_tunable **out) + struct ctdb_tunable **out, size_t *npull) { - struct ctdb_tunable *tunable; - struct ctdb_tunable_wire *wire = (struct ctdb_tunable_wire *)buf; + struct ctdb_tunable *val; + size_t offset = 0, np; + int ret; - if (buflen < offsetof(struct ctdb_tunable_wire, name)) { - return EMSGSIZE; - } - if (wire->length > buflen) { - return EMSGSIZE; - } - if (offsetof(struct ctdb_tunable_wire, name) + wire->length < - offsetof(struct ctdb_tunable_wire, name)) { - return EMSGSIZE; - } - if (buflen < offsetof(struct ctdb_tunable_wire, name) + wire->length) { - return EMSGSIZE; + val = talloc(mem_ctx, struct ctdb_tunable); + if (val == NULL) { + return ENOMEM; } - tunable = talloc(mem_ctx, struct ctdb_tunable); - if (tunable == NULL) { - return ENOMEM; + ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->value, &np); + if (ret != 0) { + goto fail; } + offset += np; - tunable->value = wire->value; - tunable->name = talloc_memdup(tunable, wire->name, wire->length); - if (tunable->name == NULL) { - talloc_free(tunable); - return ENOMEM; + ret = ctdb_stringn_pull(buf+offset, buflen-offset, mem_ctx, + &val->name, &np); + if (ret != 0) { + goto fail; } + offset += np; - *out = tunable; + *out = val; + *npull = offset; return 0; + +fail: + talloc_free(val); + return ret; } size_t ctdb_node_flag_change_len(struct ctdb_node_flag_change *flag_change) diff --git a/ctdb/tests/src/protocol_types_compat_test.c b/ctdb/tests/src/protocol_types_compat_test.c index 7a66cdefced..c2bbb1fa771 100644 --- a/ctdb/tests/src/protocol_types_compat_test.c +++ b/ctdb/tests/src/protocol_types_compat_test.c @@ -736,6 +736,64 @@ static int ctdb_connection_pull_old(uint8_t *buf, size_t buflen, return ret; } +struct ctdb_tunable_wire { + uint32_t value; + uint32_t length; + uint8_t name[1]; +}; + +static size_t ctdb_tunable_len_old(struct ctdb_tunable *in) +{ + return offsetof(struct ctdb_tunable_wire, name) + + strlen(in->name) + 1; +} + +static void ctdb_tunable_push_old(struct ctdb_tunable *in, uint8_t *buf) +{ + struct ctdb_tunable_wire *wire = (struct ctdb_tunable_wire *)buf; + + wire->value = in->value; + wire->length = strlen(in->name) + 1; + memcpy(wire->name, in->name, wire->length); +} + +static int ctdb_tunable_pull_old(uint8_t *buf, size_t buflen, + TALLOC_CTX *mem_ctx, + struct ctdb_tunable **out) +{ + struct ctdb_tunable *val; + struct ctdb_tunable_wire *wire = (struct ctdb_tunable_wire *)buf; + + if (buflen < offsetof(struct ctdb_tunable_wire, name)) { + return EMSGSIZE; + } + if (wire->length > buflen) { + return EMSGSIZE; + } + if (offsetof(struct ctdb_tunable_wire, name) + wire->length < + offsetof(struct ctdb_tunable_wire, name)) { + return EMSGSIZE; + } + if (buflen < offsetof(struct ctdb_tunable_wire, name) + wire->length) { + return EMSGSIZE; + } + + val = talloc(mem_ctx, struct ctdb_tunable); + if (val == NULL) { + return ENOMEM; + } + + val->value = wire->value; + val->name = talloc_memdup(val, wire->name, wire->length); + if (val->name == NULL) { + talloc_free(val); + return ENOMEM; + } + + *out = val; + return 0; +} + COMPAT_TYPE3_TEST(struct ctdb_statistics, ctdb_statistics); COMPAT_TYPE3_TEST(struct ctdb_vnn_map, ctdb_vnn_map); @@ -753,6 +811,7 @@ COMPAT_TYPE3_TEST(struct ctdb_traverse_start_ext, ctdb_traverse_start_ext); COMPAT_TYPE3_TEST(struct ctdb_traverse_all_ext, ctdb_traverse_all_ext); COMPAT_TYPE3_TEST(ctdb_sock_addr, ctdb_sock_addr); COMPAT_TYPE3_TEST(struct ctdb_connection, ctdb_connection); +COMPAT_TYPE3_TEST(struct ctdb_tunable, ctdb_tunable); int main(int argc, char *argv[]) { @@ -775,6 +834,7 @@ int main(int argc, char *argv[]) COMPAT_TEST_FUNC(ctdb_traverse_all_ext)(); COMPAT_TEST_FUNC(ctdb_sock_addr)(); COMPAT_TEST_FUNC(ctdb_connection)(); + COMPAT_TEST_FUNC(ctdb_tunable)(); return 0; } diff --git a/ctdb/tests/src/protocol_types_test.c b/ctdb/tests/src/protocol_types_test.c index 70c21ac2449..f7092e74b84 100644 --- a/ctdb/tests/src/protocol_types_test.c +++ b/ctdb/tests/src/protocol_types_test.c @@ -62,7 +62,7 @@ PROTOCOL_TYPE3_TEST(struct ctdb_traverse_start_ext, ctdb_traverse_start_ext); PROTOCOL_TYPE3_TEST(struct ctdb_traverse_all_ext, ctdb_traverse_all_ext); PROTOCOL_TYPE3_TEST(ctdb_sock_addr, ctdb_sock_addr); PROTOCOL_TYPE3_TEST(struct ctdb_connection, ctdb_connection); -DEFINE_TEST(struct ctdb_tunable, ctdb_tunable); +PROTOCOL_TYPE3_TEST(struct ctdb_tunable, ctdb_tunable); DEFINE_TEST(struct ctdb_node_flag_change, ctdb_node_flag_change); DEFINE_TEST(struct ctdb_var_list, ctdb_var_list); DEFINE_TEST(struct ctdb_tunable_list, ctdb_tunable_list);