feat(config-repl): wire handle_upgrade_config() via raw packet interception
Pre-decode opcode peek in myreq_handler() captures raw packet bytes for OP_upgradeConfig before xce_decode() frees the capnp segment. Passes raw bytes to xce_upgrade_config_req_extract_raw() to extract sha256 and config blob, then delegates to do_upgrade_config_with_bytes(). Removes Task 11 dependency. Phase 2 still gated by CONF_ENABLE_UPGRADE_CONFIG.
This commit is contained in:
parent
2aae45f046
commit
5053c8d42f
3 changed files with 66 additions and 27 deletions
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "cluster.h"
|
||||
#include "config_repl.h"
|
||||
#include "controller.capnp.h"
|
||||
#include "dataq.h"
|
||||
#include "htab.h"
|
||||
#include "kvmgr.h"
|
||||
|
|
@ -158,6 +159,32 @@ static int myreq_handler(vtask_t* task)
|
|||
xce_request_t request;
|
||||
xce_reply_t reply;
|
||||
|
||||
/* Peek at opcode to decide whether to save raw bytes before xce_decode()
|
||||
* frees the capnp segment. OPCode_upgradeConfig requires the raw packet
|
||||
* for xce_upgrade_config_req_extract_raw(). */
|
||||
uint8_t *raw_pkt_copy = NULL;
|
||||
size_t raw_pkt_sz = 0;
|
||||
{
|
||||
io_packet_t *pkt = data->u.iodata.pkt;
|
||||
if (pkt && pkt->data && pkt->sz > 0) {
|
||||
struct capn peek_c;
|
||||
struct Request peek_rq;
|
||||
Request_ptr peek_rp;
|
||||
capn_init_mem(&peek_c, (const uint8_t *)pkt->data, (size_t)pkt->sz, 0);
|
||||
peek_rp.p = capn_getp(capn_root(&peek_c), 0, 1);
|
||||
read_Request(&peek_rq, peek_rp);
|
||||
capn_free(&peek_c);
|
||||
|
||||
if (peek_rq.opcode == OPCode_upgradeConfig) {
|
||||
raw_pkt_copy = (uint8_t *)malloc((size_t)pkt->sz);
|
||||
if (raw_pkt_copy) {
|
||||
memcpy(raw_pkt_copy, pkt->data, (size_t)pkt->sz);
|
||||
raw_pkt_sz = (size_t)pkt->sz;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rc = xce_decode(data->u.iodata.pkt, &request);
|
||||
|
||||
TRACE("%s cpu#%d opcode %s", __func__, task->vcpu,
|
||||
|
|
@ -233,7 +260,7 @@ static int myreq_handler(vtask_t* task)
|
|||
rc = -EAGAIN;
|
||||
break;
|
||||
}
|
||||
rc = handle_upgrade_config(c, ep, &request);
|
||||
rc = handle_upgrade_config(c, ep, &request, raw_pkt_copy, raw_pkt_sz);
|
||||
break;
|
||||
#else
|
||||
{
|
||||
|
|
@ -257,6 +284,7 @@ static int myreq_handler(vtask_t* task)
|
|||
}
|
||||
|
||||
free_Request(&request);
|
||||
free(raw_pkt_copy); /* NULL-safe: free(NULL) is a no-op */
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1131,13 +1131,8 @@ int push_config_to_standbys(cluster_t *c, const uint8_t *bytes, size_t blen,
|
|||
|
||||
/*
|
||||
* do_upgrade_config_with_bytes: core upgrade logic called after the raw
|
||||
* capnp bytes have been extracted from the wire.
|
||||
*
|
||||
* Task 11 dependency note: the upgrade_config_req_t.bytes and .sha256 fields
|
||||
* are typed as xce_data_t* (a discriminated cluster-data union) in the current
|
||||
* typemap. Extracting raw byte content from them requires the Task 11 capnp
|
||||
* Data-type shims. This helper accepts the bytes directly so that the logic
|
||||
* can be tested independently of the typemap shim work.
|
||||
* capnp bytes have been extracted from the wire via
|
||||
* xce_upgrade_config_req_extract_raw().
|
||||
*
|
||||
* Steps:
|
||||
* 0. Validate size limits
|
||||
|
|
@ -1298,28 +1293,41 @@ static int do_upgrade_config_with_bytes(cluster_t *c, endpoint_t *ep,
|
|||
}
|
||||
|
||||
#if CONF_ENABLE_UPGRADE_CONFIG
|
||||
int handle_upgrade_config(cluster_t *c, endpoint_t *ep, xce_request_t *req)
|
||||
int handle_upgrade_config(cluster_t *c, endpoint_t *ep, xce_request_t *req,
|
||||
const uint8_t *raw_pkt, size_t raw_pkt_sz)
|
||||
{
|
||||
/*
|
||||
* Task 11 dependency: upgrade_config_req_t.bytes and .sha256 are typed
|
||||
* as xce_data_t* (discriminated cluster-data union). Extracting raw
|
||||
* byte content requires the Task 11 capnp Data-type shims.
|
||||
*
|
||||
* Until Task 11 lands this handler rejects all upgrade requests with
|
||||
* -ENOSYS even when CONF_ENABLE_UPGRADE_CONFIG=1. The
|
||||
* do_upgrade_config_with_bytes() helper above contains the full
|
||||
* implementation and will be wired here in Task 11.
|
||||
*/
|
||||
(void)c;
|
||||
send_upgrade_error(ep, req, c,
|
||||
"OP_upgradeConfig byte extraction requires Task 11"
|
||||
" typemap shims -- not yet available");
|
||||
return -ENOSYS;
|
||||
uint8_t *in_bytes = NULL;
|
||||
size_t in_len = 0;
|
||||
uint8_t *in_sha = NULL;
|
||||
|
||||
int rc = xce_upgrade_config_req_extract_raw(raw_pkt, raw_pkt_sz,
|
||||
&in_bytes, &in_len, &in_sha);
|
||||
if (rc != 0 || !in_bytes || !in_sha) {
|
||||
send_upgrade_error(ep, req, c,
|
||||
"Failed to extract bytes from UpgradeConfigRequest");
|
||||
free(in_bytes);
|
||||
free(in_sha);
|
||||
return rc != 0 ? rc : -EINVAL;
|
||||
}
|
||||
if (in_len == 0) {
|
||||
free(in_bytes);
|
||||
free(in_sha);
|
||||
send_upgrade_error(ep, req, c, "bytes or sha256 field missing");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = do_upgrade_config_with_bytes(c, ep, req, in_bytes, in_len, in_sha);
|
||||
free(in_bytes);
|
||||
free(in_sha);
|
||||
return rc;
|
||||
}
|
||||
#else
|
||||
int handle_upgrade_config(cluster_t *c, endpoint_t *ep, xce_request_t *req)
|
||||
int handle_upgrade_config(cluster_t *c, endpoint_t *ep, xce_request_t *req,
|
||||
const uint8_t *raw_pkt, size_t raw_pkt_sz)
|
||||
{
|
||||
(void)c;
|
||||
(void)raw_pkt;
|
||||
(void)raw_pkt_sz;
|
||||
xce_reply_t reply;
|
||||
init_reply_by_req(&reply, req);
|
||||
reply.status = -ENOSYS;
|
||||
|
|
|
|||
|
|
@ -115,10 +115,13 @@ int push_config_to_standbys(cluster_t *c, const uint8_t *bytes, size_t blen,
|
|||
|
||||
/*
|
||||
* handle_upgrade_config: handle an OP_upgradeConfig request from an admin tool.
|
||||
* Validates, stores, and fans out the new config blob; triggers restart.
|
||||
* raw_pkt/raw_pkt_sz are the on-wire capnp bytes captured before xce_decode()
|
||||
* freed the capnp segment; xce_upgrade_config_req_extract_raw() uses them to
|
||||
* recover sha256 and the config blob.
|
||||
* Only callable when CONF_ENABLE_UPGRADE_CONFIG is set.
|
||||
*/
|
||||
int handle_upgrade_config(cluster_t *c, endpoint_t *ep, xce_request_t *req);
|
||||
int handle_upgrade_config(cluster_t *c, endpoint_t *ep, xce_request_t *req,
|
||||
const uint8_t *raw_pkt, size_t raw_pkt_sz);
|
||||
|
||||
/*
|
||||
* sanitise_cn: copy at most maxlen printable ASCII chars from src to a
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue