From nobody Mon Feb 9 00:42:02 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1603992316; cv=none; d=zohomail.com; s=zohoarc; b=Lyt4IWrfPnHRN9cSH4CxnPQVNoDAq/SYlxpyLxxgL8x9txctf8NwcycWUp7HGW3NV3CcJsHoaRlXvC6veDpCiBWsJBd2VWbzZBN0VxrphRdV1TdPyRnI7D1PwboD9nkCyZR8D9/JuuclFR2CK9t97Gs21nOVrVAuZLTE4f9SQnA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1603992316; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=vDSMlFXnzPOXkYBGrnj7LwkLFSBsc9LnEOe7WzFsods=; b=atqfbJBHgUtpM/Q1dp8zI0cHxyEMptZi6oozzy8Bj1u5ynf6Wew08T3A2HyM99MdXwgFjVPPdX2kwoAKTyQC34yFI+lWT+dKVW/fWvGbTdy9Dc+bG8yaiCJUaDLDS2Vtgxmm3z1vGQEav+13M9z9u+uHdwDActutfuabFFzXE+U= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1603992316749563.0888776161488; Thu, 29 Oct 2020 10:25:16 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.14512.35875 (Exim 4.92) (envelope-from ) id 1kYBfJ-00068T-Dd; Thu, 29 Oct 2020 17:24:45 +0000 Received: by outflank-mailman (output) from mailman id 14512.35875; Thu, 29 Oct 2020 17:24:45 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1kYBfJ-00068L-AL; Thu, 29 Oct 2020 17:24:45 +0000 Received: by outflank-mailman (input) for mailman id 14512; Thu, 29 Oct 2020 17:24:44 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1kYBbr-0003MC-N9 for xen-devel@lists.xenproject.org; Thu, 29 Oct 2020 17:21:11 +0000 Received: from mo4-p03-ob.smtp.rzone.de (unknown [81.169.146.174]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id b0bcea0f-e8b5-44b9-9aff-c228c6f43efc; Thu, 29 Oct 2020 17:20:24 +0000 (UTC) Received: from sender by smtp.strato.de (RZmta 47.3.0 DYNA|AUTH) with ESMTPSA id j0b1afw9THKG3fT (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256 bits)) (Client did not present a certificate); Thu, 29 Oct 2020 18:20:16 +0100 (CET) Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1kYBbr-0003MC-N9 for xen-devel@lists.xenproject.org; Thu, 29 Oct 2020 17:21:11 +0000 Received: from mo4-p03-ob.smtp.rzone.de (unknown [81.169.146.174]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id b0bcea0f-e8b5-44b9-9aff-c228c6f43efc; Thu, 29 Oct 2020 17:20:24 +0000 (UTC) Received: from sender by smtp.strato.de (RZmta 47.3.0 DYNA|AUTH) with ESMTPSA id j0b1afw9THKG3fT (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256 bits)) (Client did not present a certificate); Thu, 29 Oct 2020 18:20:16 +0100 (CET) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: b0bcea0f-e8b5-44b9-9aff-c228c6f43efc DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1603992023; s=strato-dkim-0002; d=aepfle.de; h=References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: X-RZG-CLASS-ID:X-RZG-AUTH:From:Subject:Sender; bh=vDSMlFXnzPOXkYBGrnj7LwkLFSBsc9LnEOe7WzFsods=; b=pYItbwo0qq88TgAn5HU4aLCh4QxzQogCseTejXzbnL0cbd20RgqH38jj2mJtia1c3v y+yCnu9G1+2TtlSGdgB49SL4/J6gxS1DRNN0byKMgN4bnbzK3+E0IsXVlmvxmoMRMjOQ uxNmi4/LYnJ1hSVdRZg1QtxE59bjusMXx5eye3qcRfuC3cUkRFCF+d3rer9FExlodscC cOx5bWAnf4x4q1jvkSlvEzRNVNfiHIKxigAwCyILxoycLHS3+2RW98Fokt8oTZxqjfga H8GFbybybV4huVmGx05OnrDJdu83Tm9YKgfNI//z4y0nMaaDrxTbmMrRmo74m8dJ4uux ufVw== X-RZG-AUTH: ":P2EQZWCpfu+qG7CngxMFH1J+3q8wa/QXkBR9MXjAuzBW/OdlBZQ4AHSS3G1Jjw==" X-RZG-CLASS-ID: mo00 From: Olaf Hering To: xen-devel@lists.xenproject.org Cc: Olaf Hering , Ian Jackson , Wei Liu , Anthony PERARD Subject: [PATCH v1 21/23] tools/guest: restore: split record processing Date: Thu, 29 Oct 2020 18:20:01 +0100 Message-Id: <20201029172004.17219-22-olaf@aepfle.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201029172004.17219-1-olaf@aepfle.de> References: <20201029172004.17219-1-olaf@aepfle.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" handle_page_data must be able to read directly into mapped guest memory. This will avoid unneccesary memcpy calls for data which can be consumed ver= batim. Rearrange the code to allow decisions based on the incoming record. This change is preparation for future changes in handle_page_data, no change in behavior is intended. Signed-off-by: Olaf Hering --- tools/libs/guest/xg_sr_common.c | 33 ++++++++++++--------- tools/libs/guest/xg_sr_common.h | 4 ++- tools/libs/guest/xg_sr_restore.c | 49 ++++++++++++++++++++++---------- tools/libs/guest/xg_sr_save.c | 7 ++++- 4 files changed, 63 insertions(+), 30 deletions(-) diff --git a/tools/libs/guest/xg_sr_common.c b/tools/libs/guest/xg_sr_commo= n.c index 17567ab133..cabde4ef74 100644 --- a/tools/libs/guest/xg_sr_common.c +++ b/tools/libs/guest/xg_sr_common.c @@ -91,26 +91,33 @@ int write_split_record(struct xc_sr_context *ctx, struc= t xc_sr_record *rec, return -1; } =20 -int read_record(struct xc_sr_context *ctx, int fd, struct xc_sr_record *re= c) +int read_record_header(struct xc_sr_context *ctx, int fd, struct xc_sr_rhd= r *rhdr) { xc_interface *xch =3D ctx->xch; - struct xc_sr_rhdr rhdr; - size_t datasz; =20 - if ( read_exact(fd, &rhdr, sizeof(rhdr)) ) + if ( read_exact(fd, rhdr, sizeof(*rhdr)) ) { PERROR("Failed to read Record Header from stream"); return -1; } =20 - if ( rhdr.length > REC_LENGTH_MAX ) + if ( rhdr->length > REC_LENGTH_MAX ) { - ERROR("Record (0x%08x, %s) length %#x exceeds max (%#x)", rhdr.typ= e, - rec_type_to_str(rhdr.type), rhdr.length, REC_LENGTH_MAX); + ERROR("Record (0x%08x, %s) length %#x exceeds max (%#x)", rhdr->ty= pe, + rec_type_to_str(rhdr->type), rhdr->length, REC_LENGTH_MAX); return -1; } =20 - datasz =3D ROUNDUP(rhdr.length, REC_ALIGN_ORDER); + return 0; +} + +int read_record_data(struct xc_sr_context *ctx, int fd, struct xc_sr_rhdr = *rhdr, + struct xc_sr_record *rec) +{ + xc_interface *xch =3D ctx->xch; + size_t datasz; + + datasz =3D ROUNDUP(rhdr->length, REC_ALIGN_ORDER); =20 if ( datasz ) { @@ -119,7 +126,7 @@ int read_record(struct xc_sr_context *ctx, int fd, stru= ct xc_sr_record *rec) if ( !rec->data ) { ERROR("Unable to allocate %zu bytes for record data (0x%08x, %= s)", - datasz, rhdr.type, rec_type_to_str(rhdr.type)); + datasz, rhdr->type, rec_type_to_str(rhdr->type)); return -1; } =20 @@ -128,18 +135,18 @@ int read_record(struct xc_sr_context *ctx, int fd, st= ruct xc_sr_record *rec) free(rec->data); rec->data =3D NULL; PERROR("Failed to read %zu bytes of data for record (0x%08x, %= s)", - datasz, rhdr.type, rec_type_to_str(rhdr.type)); + datasz, rhdr->type, rec_type_to_str(rhdr->type)); return -1; } } else rec->data =3D NULL; =20 - rec->type =3D rhdr.type; - rec->length =3D rhdr.length; + rec->type =3D rhdr->type; + rec->length =3D rhdr->length; =20 return 0; -}; +} =20 static void __attribute__((unused)) build_assertions(void) { diff --git a/tools/libs/guest/xg_sr_common.h b/tools/libs/guest/xg_sr_commo= n.h index 3fe665b91d..66d1b0dfe6 100644 --- a/tools/libs/guest/xg_sr_common.h +++ b/tools/libs/guest/xg_sr_common.h @@ -475,7 +475,9 @@ static inline int write_record(struct xc_sr_context *ct= x, * * On failure, the contents of the record structure are undefined. */ -int read_record(struct xc_sr_context *ctx, int fd, struct xc_sr_record *re= c); +int read_record_header(struct xc_sr_context *ctx, int fd, struct xc_sr_rhd= r *rhdr); +int read_record_data(struct xc_sr_context *ctx, int fd, struct xc_sr_rhdr = *rhdr, + struct xc_sr_record *rec); =20 /* * This would ideally be private in restore.c, but is needed by diff --git a/tools/libs/guest/xg_sr_restore.c b/tools/libs/guest/xg_sr_rest= ore.c index 71b39612ee..93f69b9ba8 100644 --- a/tools/libs/guest/xg_sr_restore.c +++ b/tools/libs/guest/xg_sr_restore.c @@ -471,7 +471,7 @@ static int send_checkpoint_dirty_pfn_list(struct xc_sr_= context *ctx) return rc; } =20 -static int process_record(struct xc_sr_context *ctx, struct xc_sr_record *= rec); +static int process_buffered_record(struct xc_sr_context *ctx, struct xc_sr= _record *rec); static int handle_checkpoint(struct xc_sr_context *ctx) { xc_interface *xch =3D ctx->xch; @@ -510,7 +510,7 @@ static int handle_checkpoint(struct xc_sr_context *ctx) =20 for ( i =3D 0; i < ctx->restore.buffered_rec_num; i++ ) { - rc =3D process_record(ctx, &ctx->restore.buffered_records[i]); + rc =3D process_buffered_record(ctx, &ctx->restore.buffered_rec= ords[i]); if ( rc ) goto err; } @@ -571,10 +571,11 @@ static int handle_checkpoint(struct xc_sr_context *ct= x) return rc; } =20 -static int buffer_record(struct xc_sr_context *ctx, struct xc_sr_record *r= ec) +static int buffer_record(struct xc_sr_context *ctx, struct xc_sr_rhdr *rhd= r) { xc_interface *xch =3D ctx->xch; unsigned int new_alloc_num; + struct xc_sr_record rec; struct xc_sr_record *p; =20 if ( ctx->restore.buffered_rec_num >=3D ctx->restore.allocated_rec_num= ) @@ -592,8 +593,13 @@ static int buffer_record(struct xc_sr_context *ctx, st= ruct xc_sr_record *rec) ctx->restore.allocated_rec_num =3D new_alloc_num; } =20 + if ( read_record_data(ctx, ctx->fd, rhdr, &rec) ) + { + return -1; + } + memcpy(&ctx->restore.buffered_records[ctx->restore.buffered_rec_num++], - rec, sizeof(*rec)); + &rec, sizeof(rec)); =20 return 0; } @@ -624,7 +630,7 @@ int handle_static_data_end(struct xc_sr_context *ctx) return rc; } =20 -static int process_record(struct xc_sr_context *ctx, struct xc_sr_record *= rec) +static int process_buffered_record(struct xc_sr_context *ctx, struct xc_sr= _record *rec) { xc_interface *xch =3D ctx->xch; int rc =3D 0; @@ -662,6 +668,19 @@ static int process_record(struct xc_sr_context *ctx, s= truct xc_sr_record *rec) return rc; } =20 +static int process_incoming_record_header(struct xc_sr_context *ctx, struc= t xc_sr_rhdr *rhdr) +{ + struct xc_sr_record rec; + int rc; + + rc =3D read_record_data(ctx, ctx->fd, rhdr, &rec); + if ( rc ) + return rc; + + return process_buffered_record(ctx, &rec); +} + + static int setup(struct xc_sr_context *ctx) { xc_interface *xch =3D ctx->xch; @@ -745,7 +764,7 @@ static void cleanup(struct xc_sr_context *ctx) static int restore(struct xc_sr_context *ctx) { xc_interface *xch =3D ctx->xch; - struct xc_sr_record rec; + struct xc_sr_rhdr rhdr; int rc, saved_rc =3D 0, saved_errno =3D 0; =20 IPRINTF("Restoring domain"); @@ -756,7 +775,7 @@ static int restore(struct xc_sr_context *ctx) =20 do { - rc =3D read_record(ctx, ctx->fd, &rec); + rc =3D read_record_header(ctx, ctx->fd, &rhdr); if ( rc ) { if ( ctx->restore.buffer_all_records ) @@ -766,25 +785,25 @@ static int restore(struct xc_sr_context *ctx) } =20 if ( ctx->restore.buffer_all_records && - rec.type !=3D REC_TYPE_END && - rec.type !=3D REC_TYPE_CHECKPOINT ) + rhdr.type !=3D REC_TYPE_END && + rhdr.type !=3D REC_TYPE_CHECKPOINT ) { - rc =3D buffer_record(ctx, &rec); + rc =3D buffer_record(ctx, &rhdr); if ( rc ) goto err; } else { - rc =3D process_record(ctx, &rec); + rc =3D process_incoming_record_header(ctx, &rhdr); if ( rc =3D=3D RECORD_NOT_PROCESSED ) { - if ( rec.type & REC_TYPE_OPTIONAL ) + if ( rhdr.type & REC_TYPE_OPTIONAL ) DPRINTF("Ignoring optional record %#x (%s)", - rec.type, rec_type_to_str(rec.type)); + rhdr.type, rec_type_to_str(rhdr.type)); else { ERROR("Mandatory record %#x (%s) not handled", - rec.type, rec_type_to_str(rec.type)); + rhdr.type, rec_type_to_str(rhdr.type)); rc =3D -1; goto err; } @@ -795,7 +814,7 @@ static int restore(struct xc_sr_context *ctx) goto err; } =20 - } while ( rec.type !=3D REC_TYPE_END ); + } while ( rhdr.type !=3D REC_TYPE_END ); =20 remus_failover: if ( ctx->stream_type =3D=3D XC_STREAM_COLO ) diff --git a/tools/libs/guest/xg_sr_save.c b/tools/libs/guest/xg_sr_save.c index 804e4ccb3a..9be5e8c52b 100644 --- a/tools/libs/guest/xg_sr_save.c +++ b/tools/libs/guest/xg_sr_save.c @@ -590,6 +590,7 @@ static int send_memory_live(struct xc_sr_context *ctx) static int colo_merge_secondary_dirty_bitmap(struct xc_sr_context *ctx) { xc_interface *xch =3D ctx->xch; + struct xc_sr_rhdr rhdr; struct xc_sr_record rec; uint64_t *pfns =3D NULL; uint64_t pfn; @@ -598,7 +599,11 @@ static int colo_merge_secondary_dirty_bitmap(struct xc= _sr_context *ctx) DECLARE_HYPERCALL_BUFFER_SHADOW(unsigned long, dirty_bitmap, &ctx->save.dirty_bitmap_hbuf); =20 - rc =3D read_record(ctx, ctx->save.recv_fd, &rec); + rc =3D read_record_header(ctx, ctx->save.recv_fd, &rhdr); + if ( rc ) + goto err; + + rc =3D read_record_data(ctx, ctx->save.recv_fd, &rhdr, &rec); if ( rc ) goto err; =20