[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


  • To: Julien Grall <julien@xxxxxxx>
  • From: Luca Fancellu <luca.fancellu@xxxxxxx>
  • Date: Mon, 21 Jun 2021 09:55:48 +0100
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=arm.com; dmarc=pass action=none header.from=arm.com; dkim=pass header.d=arm.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=yrAjr5G1UUQrp36qRjGeyweSc9U2mkXfIlhg8j21I1Q=; b=hXAbiQf6+1AIvsHYYBaoM5ggs2TE5jPz2zZXGRtdOLVyHT7MgeebPdfh58WsTzuB6uDfEwaaXEglX1HYuiMsCgw90liwbkBQMbBzCvSEaLoYIPsTTsLE9oG+2aIVzNJXb8afd9DasWPO4sfwEcvjUsbqN+l7p09hToUgEI1fzLWYZs0viCQtLbit/l/Muedmr8JEkhaX9eySa38+8/L/1mpyE9Hv1D8mzr/0gDAIdoZiBsyYlv+MmcUC/0qE3bBe8GR0e4XosusIrIUhFc4Pp5arhenN24AkAF8+1Rt6eMaKJawh0E3qobAgh9GU6yQuKoJ9Xoj7mwtDiuFQEJnzeA==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Arr2vYD7lJ7Bxsz5sfUCYhRlaYksr90xhoSo0MilaGCn7i3/Qpk0udrF5qfwGH8cH66vWHToFVGgSkJO4L1/pemHsa01eIBGqH4LD8kK39IaHQwpiEQwr+DOkqWlNxFz21nLdZJjxLtPIibq3qoKCk1WNgMmf6Vz1NYZDzuG7XHkQo+nZqxDcGQ1CJLbPJjd0SK4+12124x0GUaEAR/pb4M+u7udE7GDOyqamD+bdOZ7soUGSc7Yy04nGmiDsOv9ntR6Phm7IMbwIarI9rE1Zk+1LqhvSmn7TiM93VKpNHaEFmUZ3kvVKmSzMcBnRDImjb5OwL/aegVYD7vgrvQYOQ==
  • Authentication-results-original: xen.org; dkim=none (message not signed) header.d=none;xen.org; dmarc=none action=none header.from=arm.com;
  • Cc: xen-devel@xxxxxxxxxxxxxxxxxxxx, raphning@xxxxxxxxxxxx, doebel@xxxxxxxxx, Julien Grall <jgrall@xxxxxxxxxx>, Ian Jackson <iwj@xxxxxxxxxxxxxx>, Wei Liu <wl@xxxxxxx>, Juergen Gross <jgross@xxxxxxxx>
  • Delivery-date: Mon, 21 Jun 2021 08:56:56 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Nodisclaimer: true
  • Original-authentication-results: xen.org; dkim=none (message not signed) header.d=none;xen.org; dmarc=none action=none header.from=arm.com;


> 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
> 
> 




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.