[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH 03/10] tools/xenstore: Don't assume conn->in points to the LU request
> On 16 Jun 2021, at 15:43, Julien Grall <julien@xxxxxxx> wrote: > > From: Julien Grall <jgrall@xxxxxxxxxx> > > call_delayed() is currently assuming that conn->in is NULL when > handling delayed request. However, the connection is not paused. > Therefore new request can be processed and conn->in may be non-NULL > if we have only received a partial request. > > Furthermore, as we overwrite conn->in, the current partial request > will not be transferred. This will result to corrupt the connection. > > Rather than updating conn->in, stash the LU request in lu_status and > let each callback for delayed request to update conn->in when > necessary. > > To keep a sane interface, the code to write the "OK" response the > LU request is moved in xenstored_core.c. > > Fixes: c5ca1404b4 ("tools/xenstore: add support for delaying execution of a > xenstore request") > Fixes: ed6eebf17d ("tools/xenstore: dump the xenstore state for live update") > Signed-off-by: Julien Grall <jgrall@xxxxxxxxxx> > > ---- > > This is fixing bugs from two separate commits. I couldn't figure out > how to split in two patches without breaking bisection. > --- > tools/xenstore/xenstored_control.c | 41 ++++++++++++++++++++++++++++-- > tools/xenstore/xenstored_control.h | 3 +++ > tools/xenstore/xenstored_core.c | 17 +++---------- > 3 files changed, 46 insertions(+), 15 deletions(-) > > diff --git a/tools/xenstore/xenstored_control.c > b/tools/xenstore/xenstored_control.c > index d08a2b961432..7acc2d134f9f 100644 > --- a/tools/xenstore/xenstored_control.c > +++ b/tools/xenstore/xenstored_control.c > @@ -50,6 +50,9 @@ struct live_update { > /* For verification the correct connection is acting. */ > struct connection *conn; > > + /* Pointer to the command used to request LU */ > + struct buffered_data *in; > + > #ifdef __MINIOS__ > void *kernel; > unsigned int kernel_size; > @@ -100,6 +103,7 @@ static const char *lu_begin(struct connection *conn) > if (!lu_status) > return "Allocation failure."; > lu_status->conn = conn; > + lu_status->in = conn->in; > talloc_set_destructor(lu_status, lu_destroy); > > return NULL; > @@ -110,11 +114,34 @@ struct connection *lu_get_connection(void) > return lu_status ? lu_status->conn : NULL; > } > > +unsigned int lu_write_response(FILE *fp) > +{ > + struct xsd_sockmsg msg; > + > + assert(lu_status); > + > + msg = lu_status->in->hdr.msg; > + > + msg.len = sizeof("OK"); > + if (fp && fwrite(&msg, sizeof(msg), 1, fp) != 1) > + return 0; > + if (fp && fwrite("OK", msg.len, 1, fp) != 1) > + return 0; > + > + return sizeof(msg) + msg.len; > +} > + > #else > struct connection *lu_get_connection(void) > { > return NULL; > } > + > +unsigned int lu_write_response(FILE *fp) > +{ > + /* Unsupported */ > + return 0; > +} > #endif > > struct cmd_s { > @@ -658,6 +685,8 @@ static bool do_lu_start(struct delayed_request *req) > { > time_t now = time(NULL); > const char *ret; > + struct buffered_data *saved_in; > + struct connection *conn = lu_status->conn; > > if (!lu_check_lu_allowed()) { > if (now < lu_status->started_at + lu_status->timeout) > @@ -668,8 +697,9 @@ static bool do_lu_start(struct delayed_request *req) > } > } > > + assert(req->in == lu_status->in); > /* Dump out internal state, including "OK" for live update. */ > - ret = lu_dump_state(req->in, lu_status->conn); > + ret = lu_dump_state(req->in, conn); > if (!ret) { > /* Perform the activation of new binary. */ > ret = lu_activate_binary(req->in); > @@ -677,7 +707,14 @@ static bool do_lu_start(struct delayed_request *req) > > /* We will reach this point only in case of failure. */ > out: > - send_reply(lu_status->conn, XS_CONTROL, ret, strlen(ret) + 1); > + /* > + * send_reply() will send the response for conn->in. Save the current > + * conn->in and restore it afterwards. > + */ > + saved_in = conn->in; > + conn->in = req->in; > + send_reply(conn, XS_CONTROL, ret, strlen(ret) + 1); > + conn->in = saved_in; > talloc_free(lu_status); > > return true; > diff --git a/tools/xenstore/xenstored_control.h > b/tools/xenstore/xenstored_control.h > index 6842b8d88760..27d7f19e4b7f 100644 > --- a/tools/xenstore/xenstored_control.h > +++ b/tools/xenstore/xenstored_control.h > @@ -20,3 +20,6 @@ int do_control(struct connection *conn, struct > buffered_data *in); > void lu_read_state(void); > > struct connection *lu_get_connection(void); > + > +/* Write the "OK" response for the live-update command */ > +unsigned int lu_write_response(FILE *fp); > diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c > index 607187361d84..41b26d7094c8 100644 > --- a/tools/xenstore/xenstored_core.c > +++ b/tools/xenstore/xenstored_core.c > @@ -272,15 +272,10 @@ static int undelay_request(void *_req) > > static void call_delayed(struct connection *conn, struct delayed_request *req) Here the conn parameter is not needed anymore, or am I missing something? Cheers, Luca > { > - assert(conn->in == NULL); > - conn->in = req->in; > - > if (req->func(req)) { > undelay_request(req); > talloc_set_destructor(req, NULL); > } > - > - conn->in = NULL; > } > > int delay_request(struct connection *conn, struct buffered_data *in, > @@ -2375,7 +2370,7 @@ const char *dump_state_buffered_data(FILE *fp, const > struct connection *c, > struct buffered_data *out, *in = c->in; > bool partial = true; > > - if (in && c != lu_get_connection()) { > + if (in) { > len = in->inhdr ? in->used : sizeof(in->hdr); > if (fp && fwrite(&in->hdr, len, 1, fp) != 1) > return "Dump read data error"; > @@ -2416,16 +2411,12 @@ const char *dump_state_buffered_data(FILE *fp, const > struct connection *c, > > /* Add "OK" for live-update command. */ > if (c == lu_get_connection()) { > - struct xsd_sockmsg msg = c->in->hdr.msg; > + unsigned int rc = lu_write_response(fp); > > - msg.len = sizeof("OK"); > - if (fp && fwrite(&msg, sizeof(msg), 1, fp) != 1) > + if (!rc) > return "Dump buffered data error"; > - len += sizeof(msg); > - if (fp && fwrite("OK", msg.len, 1, fp) != 1) > > - return "Dump buffered data error"; > - len += msg.len; > + len += rc; > } > > if (sc) > -- > 2.17.1 > >
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |