From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34771) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YWDxj-0004qY-NK for qemu-devel@nongnu.org; Thu, 12 Mar 2015 21:00:29 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YWDxa-0006iW-Rh for qemu-devel@nongnu.org; Thu, 12 Mar 2015 21:00:27 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:58011) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YWDxa-0006gY-6q for qemu-devel@nongnu.org; Thu, 12 Mar 2015 21:00:18 -0400 Date: Fri, 13 Mar 2015 11:55:58 +1100 From: David Gibson Message-ID: <20150313005558.GY11973@voom.redhat.com> References: <1424883128-9841-1-git-send-email-dgilbert@redhat.com> <1424883128-9841-19-git-send-email-dgilbert@redhat.com> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="MziYxCZO8WOaTd4I" Content-Disposition: inline In-Reply-To: <1424883128-9841-19-git-send-email-dgilbert@redhat.com> Subject: Re: [Qemu-devel] [PATCH v5 18/45] MIG_CMD_PACKAGED: Send a packaged chunk of migration stream List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: "Dr. David Alan Gilbert (git)" Cc: aarcange@redhat.com, yamahata@private.email.ne.jp, quintela@redhat.com, qemu-devel@nongnu.org, amit.shah@redhat.com, pbonzini@redhat.com, yanghy@cn.fujitsu.com --MziYxCZO8WOaTd4I Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Wed, Feb 25, 2015 at 04:51:41PM +0000, Dr. David Alan Gilbert (git) wrot= e: > From: "Dr. David Alan Gilbert" >=20 > MIG_CMD_PACKAGED is a migration command that allows a chunk > of migration stream to be sent in one go, and be received by > a separate instance of the loadvm loop while not interacting > with the migration stream. Hrm. I'd be more comfortable if the semantics of CMD_PACKAGED were defined in terms of visible effects on the other end, rather than in terms of how it's implemented internally. > This is used by postcopy to load device state (from the package) > while loading memory pages from the main stream. Which makes the above paragraph a bit misleading - the whole point here is that loading the package data *does* interact with the migration stream - just that it's the migration stream after the end of the package. > Signed-off-by: Dr. David Alan Gilbert > --- > include/sysemu/sysemu.h | 4 +++ > savevm.c | 82 +++++++++++++++++++++++++++++++++++++++++++= ++++++ > trace-events | 4 +++ > 3 files changed, 90 insertions(+) >=20 > diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h > index d6a6d51..e83bf80 100644 > --- a/include/sysemu/sysemu.h > +++ b/include/sysemu/sysemu.h > @@ -87,6 +87,7 @@ enum qemu_vm_cmd { > MIG_CMD_INVALID =3D 0, /* Must be 0 */ > MIG_CMD_OPEN_RETURN_PATH, /* Tell the dest to open the Return path = */ > MIG_CMD_PING, /* Request a PONG on the RP */ > + MIG_CMD_PACKAGED, /* Send a wrapped stream within this stre= am */ > =20 > MIG_CMD_POSTCOPY_ADVISE =3D 20, /* Prior to any page transfers, just > warn we might want to do PC */ > @@ -101,6 +102,8 @@ enum qemu_vm_cmd { > =20 > }; > =20 > +#define MAX_VM_CMD_PACKAGED_SIZE (1ul << 24) > + > bool qemu_savevm_state_blocked(Error **errp); > void qemu_savevm_state_begin(QEMUFile *f, > const MigrationParams *params); > @@ -113,6 +116,7 @@ void qemu_savevm_command_send(QEMUFile *f, enum qemu_= vm_cmd command, > uint16_t len, uint8_t *data); > void qemu_savevm_send_ping(QEMUFile *f, uint32_t value); > void qemu_savevm_send_open_return_path(QEMUFile *f); > +void qemu_savevm_send_packaged(QEMUFile *f, const QEMUSizedBuffer *qsb); > void qemu_savevm_send_postcopy_advise(QEMUFile *f); > void qemu_savevm_send_postcopy_listen(QEMUFile *f); > void qemu_savevm_send_postcopy_run(QEMUFile *f); > diff --git a/savevm.c b/savevm.c > index e31ccb0..f65bff3 100644 > --- a/savevm.c > +++ b/savevm.c > @@ -636,6 +636,38 @@ void qemu_savevm_send_open_return_path(QEMUFile *f) > qemu_savevm_command_send(f, MIG_CMD_OPEN_RETURN_PATH, 0, NULL); > } > =20 > +/* We have a buffer of data to send; we don't want that all to be loaded > + * by the command itself, so the command contains just the length of the > + * extra buffer that we then send straight after it. > + * TODO: Must be a better way to organise that > + */ > +void qemu_savevm_send_packaged(QEMUFile *f, const QEMUSizedBuffer *qsb) > +{ > + size_t cur_iov; > + size_t len =3D qsb_get_length(qsb); > + uint32_t tmp; > + > + tmp =3D cpu_to_be32(len); > + > + trace_qemu_savevm_send_packaged(); > + qemu_savevm_command_send(f, MIG_CMD_PACKAGED, 4, (uint8_t *)&tmp); > + > + /* all the data follows (concatinating the iov's) */ > + for (cur_iov =3D 0; cur_iov < qsb->n_iov; cur_iov++) { > + /* The iov entries are partially filled */ > + size_t towrite =3D (qsb->iov[cur_iov].iov_len > len) ? > + len : > + qsb->iov[cur_iov].iov_len; > + len -=3D towrite; > + > + if (!towrite) { > + break; > + } > + > + qemu_put_buffer(f, qsb->iov[cur_iov].iov_base, towrite); > + } > +} > + > /* Send prior to any postcopy transfer */ > void qemu_savevm_send_postcopy_advise(QEMUFile *f) > { > @@ -1265,6 +1297,48 @@ static int loadvm_process_command_simple_lencheck(= const char *name, > return 0; > } > =20 > +/* Immediately following this command is a blob of data containing an em= bedded > + * chunk of migration stream; read it and load it. > + */ > +static int loadvm_handle_cmd_packaged(MigrationIncomingState *mis, > + uint32_t length) > +{ > + int ret; > + uint8_t *buffer; > + QEMUSizedBuffer *qsb; > + > + trace_loadvm_handle_cmd_packaged(length); > + > + if (length > MAX_VM_CMD_PACKAGED_SIZE) { > + error_report("Unreasonably large packaged state: %u", length); > + return -1; It would be a good idea to check this on the send side as well as receive, wouldn't it? > + } > + buffer =3D g_malloc0(length); > + ret =3D qemu_get_buffer(mis->file, buffer, (int)length); > + if (ret !=3D length) { > + g_free(buffer); > + error_report("CMD_PACKAGED: Buffer receive fail ret=3D%d length= =3D%d\n", > + ret, length); > + return (re/t < 0) ? ret : -EAGAIN; > + } > + trace_loadvm_handle_cmd_packaged_received(ret); > + > + /* Setup a dummy QEMUFile that actually reads from the buffer */ > + qsb =3D qsb_create(buffer, length); > + g_free(buffer); /* Because qsb_create copies */ > + if (!qsb) { > + error_report("Unable to create qsb"); > + } > + QEMUFile *packf =3D qemu_bufopen("r", qsb); > + > + ret =3D qemu_loadvm_state_main(packf, mis); > + trace_loadvm_handle_cmd_packaged_main(ret); > + qemu_fclose(packf); > + qsb_free(qsb); > + > + return ret; > +} > + > /* > * Process an incoming 'QEMU_VM_COMMAND' > * negative return on error (will issue error message) > @@ -1315,6 +1389,14 @@ static int loadvm_process_command(QEMUFile *f) > migrate_send_rp_pong(mis, tmp32); > break; > =20 > + case MIG_CMD_PACKAGED: > + if (loadvm_process_command_simple_lencheck("CMD_POSTCOPY_PACKAGE= D", > + len, 4)) { > + return -1; > + } > + tmp32 =3D qemu_get_be32(f); > + return loadvm_handle_cmd_packaged(mis, tmp32); > + > case MIG_CMD_POSTCOPY_ADVISE: > if (loadvm_process_command_simple_lencheck("CMD_POSTCOPY_ADVISE", > len, 16)) { > diff --git a/trace-events b/trace-events > index 050f553..cbf995c 100644 > --- a/trace-events > +++ b/trace-events > @@ -1171,6 +1171,10 @@ qemu_loadvm_state_main(void) "" > qemu_loadvm_state_main_quit_parent(void) "" > qemu_loadvm_state_post_main(int ret) "%d" > qemu_loadvm_state_section_startfull(uint32_t section_id, const char *ids= tr, uint32_t instance_id, uint32_t version_id) "%u(%s) %u %u" > +qemu_savevm_send_packaged(void) "" > +loadvm_handle_cmd_packaged(unsigned int length) "%u" > +loadvm_handle_cmd_packaged_main(int ret) "%d" > +loadvm_handle_cmd_packaged_received(int ret) "%d" > loadvm_postcopy_handle_advise(void) "" > loadvm_postcopy_handle_end(void) "" > loadvm_postcopy_handle_listen(void) "" --=20 David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson --MziYxCZO8WOaTd4I Content-Type: application/pgp-signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAEBAgAGBQJVAjWeAAoJEGw4ysog2bOSPgcP/iKO0NnsxGJKnXoktpGvV4MW btLn/QnXVi+q3CWCUNweSsAdgEpIt02LXKV0WTYsFXcX3BFaM2CCvCDo7iy8e04V KeCdJ+h13U9b0VeGF+wyqKhaca4C1gZ3ZAv7UftV9FAO3B1mRximlohsaV9X0cXl 8B2Ju8YVxYK+vgnf7RmkFOQZOSCXqM0fOEqQ/h5qgEzWdogdEW7bLbcHYttdSrnF gx811RvxkOqkYbe+DrbV2w57NODqQKmi0TNKPGS7xpUXi+QJsnQig1kC1eHictB4 zgicK3TtQ7FPm4FiQ9XUdWbBVHBa/nyuFS0M44qz8dbKmhIW1a1wbZkq55bfw+8R 99K/MQ48bEsFBzYI7dKnJLamYIUb3jHzidxxAsqolL/7xFV/XSlyHR1pqNjqgRjd 88nBEknRN+UE354CFnUpBQgtYmSEvXYZ+Xa0MRBKOEBiT+MVymGLVPIeR2MFmP5i DbV8iJpfSCC48/rn6zku7aixAMpHF3lrAqpJ8MQrxv5IouJto1eaS8Hy8ef9vHtU tSPIZJrF+me79LQY8X/7+I42Mr1ekKN6twSoAJD7ssfybSdWIskrnHQCeXgMd6xg xq0gtAiTDkzDDjdaqNDgzmoJMygIXs0nax0nckUxCOB3iPJ4HGgETuZAEvtsP1KX VOaiv40hJWFqXuAqKqWC =bzXC -----END PGP SIGNATURE----- --MziYxCZO8WOaTd4I--