From nobody Mon Feb 9 19:06:22 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=fail (Bad Signature) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1622564056050168.81542911988583; Tue, 1 Jun 2021 09:14:16 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.135041.251284 (Exim 4.92) (envelope-from ) id 1lo71j-0004N6-Kj; Tue, 01 Jun 2021 16:13:59 +0000 Received: by outflank-mailman (output) from mailman id 135041.251284; Tue, 01 Jun 2021 16:13:59 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1lo71j-0004Ml-GF; Tue, 01 Jun 2021 16:13:59 +0000 Received: by outflank-mailman (input) for mailman id 135041; Tue, 01 Jun 2021 16:13:58 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1lo70f-0005Ec-3L for xen-devel@lists.xenproject.org; Tue, 01 Jun 2021 16:12:53 +0000 Received: from mo4-p03-ob.smtp.rzone.de (unknown [85.215.255.100]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id 7758098d-fefe-4003-bede-ed93932f6711; Tue, 01 Jun 2021 16:11:41 +0000 (UTC) Received: from sender by smtp.strato.de (RZmta 47.27.2 AUTH) with ESMTPSA id j0415bx51GBZ1BT (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits)) (Client did not present a certificate); Tue, 1 Jun 2021 18:11:35 +0200 (CEST) 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: 7758098d-fefe-4003-bede-ed93932f6711 ARC-Seal: i=1; a=rsa-sha256; t=1622563896; cv=none; d=strato.com; s=strato-dkim-0002; b=kc7Yj/zHkuxSkuv91lZrKLFhxicbkhg2PrG0a22bcdRA4EYn0v6h6gKz34AdefHZl+ EJyvTAopM/CfodrzWrb147NRFmFDJz/XfJrO6Jq8f/8Wbdt7UlIKnGzR+ASqGVGf8x+o Rz7bh5z49QsWnCQS4g0icfQs1hIRAxEswdZCD5OpCUhYm+ZXfIg816YZEcpPD4Nfy1V5 zjydUXGqGR2Xj1v26rFjjfsUcSVTbVotBX488J+WaNOEL0GgopJJbfw3cRgLIB4kjtN7 YrcfPsZcDHHS0DNoJzFRcQwLqcZXt7Hl8JOyfEOnr4Ml4duXdfmAVBqzndEfhjvBFOPl Ptkw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; t=1622563896; s=strato-dkim-0002; d=strato.com; h=References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=KiB5zmNJWHh3QN6pLulGVrCrsceJ5e3LZlNQkeTmQNs=; b=r7uWJ9iWXTHG6ECfj3bEZt5/Lo06UgF5YH3FHjvxUwYrQJPhrxCFqJHq5oHFNDo97C SOybKMZEGGtKfKZMz3cJsEZV8c3ctBTiklqKuuXHkpSDHUSwgFVW6kCLgA+vstWxE/+F QT2A0zxs/XKEOUwDxzVKMdPYXvjGTaywBIyAgdFXR3y+4/i8kycF+UwZAa1F4IhdwJ1i ujNFtHYD9wk7uVpYoywTP/4H2J3MegGylO+lGdemO9PdYrn/aOivc8An49yyOTuJmqQD ygv2ILdRbdwJYCRJO8K30tLH97nw8PPMCN5TdIjuydQqSc91dgTk2+KMIHi+d4p0pc1T B+HQ== ARC-Authentication-Results: i=1; strato.com; dkim=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1622563896; s=strato-dkim-0002; d=aepfle.de; h=References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=KiB5zmNJWHh3QN6pLulGVrCrsceJ5e3LZlNQkeTmQNs=; b=naDXOxfkmm5wQsb35m1m/5F9QiDgv5TjkdmqtNiP/cHO0E/XhKL7kQ+OO/+eZQCN89 GMxdCnfgXCAPoEFvvA8CLNwAr8eXorkxeI2UcQCmm1TNdnNqoPIpnYqBsmeSi/gBS9TT sxQAmMKxtGaMvAe2papjTwG9uhxBk8hp7zNQcjqUDEX9331uoZswbOf7DvJ2lmmtm/G9 wTjQizEt0u5TTUcUFcsWjxNOs6/P+GjUkFYzA60hJLufZHtZ2GJcFWx3qw4GvXWdDmNM /jdcYxg0pVu2F14esr9R6Vw0uOMap4adylS5ifs+pwqOsAUjlO2ZZGyTGT4dubU8atdd a0sg== Authentication-Results: strato.com; dkim=none X-RZG-AUTH: ":P2EQZWCpfu+qG7CngxMFH1J+3q8wa/QXkBR9MXjAuzpIG0mv9coXAgs09ValFcstyKtnZMLOo4jr88Zf5nXI1mYJUK+h" X-RZG-CLASS-ID: mo00 From: Olaf Hering To: xen-devel@lists.xenproject.org Cc: Olaf Hering , Ian Jackson , Wei Liu Subject: [PATCH v20210601 24/38] tools/guest: restore: split record processing Date: Tue, 1 Jun 2021 18:11:04 +0200 Message-Id: <20210601161118.18986-25-olaf@aepfle.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210601161118.18986-1-olaf@aepfle.de> References: <20210601161118.18986-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 Reviewed-by: Juergen Gross --- tools/libs/saverestore/common.c | 33 ++++++++++++--------- tools/libs/saverestore/common.h | 4 ++- tools/libs/saverestore/restore.c | 49 ++++++++++++++++++++++---------- tools/libs/saverestore/save.c | 7 ++++- 4 files changed, 63 insertions(+), 30 deletions(-) diff --git a/tools/libs/saverestore/common.c b/tools/libs/saverestore/commo= n.c index 77128bc747..7da7fa4e2c 100644 --- a/tools/libs/saverestore/common.c +++ b/tools/libs/saverestore/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/saverestore/common.h b/tools/libs/saverestore/commo= n.h index 9de09ae64a..73256f08ab 100644 --- a/tools/libs/saverestore/common.h +++ b/tools/libs/saverestore/common.h @@ -487,7 +487,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/saverestore/restore.c b/tools/libs/saverestore/rest= ore.c index 598a4aa06d..bb1574ed74 100644 --- a/tools/libs/saverestore/restore.c +++ b/tools/libs/saverestore/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/saverestore/save.c b/tools/libs/saverestore/save.c index c4876ba24c..b59cb069ed 100644 --- a/tools/libs/saverestore/save.c +++ b/tools/libs/saverestore/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