[libvirt] [PATCH 10/15] qemu: Store save cookie in save images and snapshots
Pavel Hrdina
phrdina at redhat.com
Tue Jun 6 14:48:14 UTC 2017
On Mon, Jun 05, 2017 at 11:26:58AM +0200, Jiri Denemark wrote:
> The following patches will add an actual content in the cookie and use
> the data when restoring a domain.
>
> Signed-off-by: Jiri Denemark <jdenemar at redhat.com>
> ---
> docs/formatsnapshot.html.in | 6 +++
> docs/schemas/domainsnapshot.rng | 7 ++++
> src/qemu/qemu_driver.c | 90 ++++++++++++++++++++++++++++++++++++-----
> 3 files changed, 93 insertions(+), 10 deletions(-)
>
> diff --git a/docs/formatsnapshot.html.in b/docs/formatsnapshot.html.in
> index c3ab516fa..5e8e21c8a 100644
> --- a/docs/formatsnapshot.html.in
> +++ b/docs/formatsnapshot.html.in
> @@ -235,6 +235,12 @@
> at the time of the snapshot (<span class="since">since
> 0.9.5</span>). Readonly.
> </dd>
> + <dt><code>cookie</code></dt>
> + <dd>Save image cookie containing additional data libvirt may need to
> + properly restore a domain from an active snapshot when such data
> + cannot be stored directly in the <code>domain</code> to maintain
> + compatibility with older libvirt or hypervisor. Readonly.
> + </dd>
> </dl>
>
> <h2><a name="example">Examples</a></h2>
> diff --git a/docs/schemas/domainsnapshot.rng b/docs/schemas/domainsnapshot.rng
> index 4ab1b828f..268088709 100644
> --- a/docs/schemas/domainsnapshot.rng
> +++ b/docs/schemas/domainsnapshot.rng
> @@ -90,6 +90,13 @@
> </element>
> </element>
> </optional>
> + <optional>
> + <element name='cookie'>
> + <zeroOrMore>
> + <ref name='customElement'/>
> + </zeroOrMore>
> + </element>
> + </optional>
> </interleave>
> </element>
> </define>
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 96077df78..10df56e61 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -2808,7 +2808,8 @@ struct _virQEMUSaveHeader {
> uint32_t data_len;
> uint32_t was_running;
> uint32_t compressed;
> - uint32_t unused[15];
> + uint32_t cookie;
I would suggest cookieOffset.
> + uint32_t unused[14];
> };
>
> typedef struct _virQEMUSaveData virQEMUSaveData;
> @@ -2816,6 +2817,7 @@ typedef virQEMUSaveData *virQEMUSaveDataPtr;
> struct _virQEMUSaveData {
> virQEMUSaveHeader header;
> char *xml;
> + char *cookie;
> };
>
>
> @@ -2826,6 +2828,7 @@ bswap_header(virQEMUSaveHeaderPtr hdr)
> hdr->data_len = bswap_32(hdr->data_len);
> hdr->was_running = bswap_32(hdr->was_running);
> hdr->compressed = bswap_32(hdr->compressed);
> + hdr->cookie = bswap_32(hdr->cookie);
> }
>
>
> @@ -2836,6 +2839,7 @@ virQEMUSaveDataFree(virQEMUSaveDataPtr data)
> return;
>
> VIR_FREE(data->xml);
> + VIR_FREE(data->cookie);
> VIR_FREE(data);
> }
>
> @@ -2845,8 +2849,10 @@ virQEMUSaveDataFree(virQEMUSaveDataPtr data)
> */
> static virQEMUSaveDataPtr
> virQEMUSaveDataNew(char *domXML,
> + qemuDomainSaveCookiePtr cookie,
I would suggest cookieObj.
> bool running,
> - int compressed)
> + int compressed,
> + virDomainXMLOptionPtr xmlopt)
> {
> virQEMUSaveDataPtr data = NULL;
> virQEMUSaveHeaderPtr header;
> @@ -2856,6 +2862,11 @@ virQEMUSaveDataNew(char *domXML,
>
> VIR_STEAL_PTR(data->xml, domXML);
>
> + if (cookie &&
> + !(data->cookie = virSaveCookieFormat((virObjectPtr) cookie,
> + virDomainXMLOptionGetSaveCookie(xmlopt))))
Here it's kind of confusing,
> + goto error;
> +
> header = &data->header;
> memcpy(header->magic, QEMU_SAVE_PARTIAL, sizeof(header->magic));
> header->version = QEMU_SAVE_VERSION;
> @@ -2863,6 +2874,10 @@ virQEMUSaveDataNew(char *domXML,
> header->compressed = compressed;
>
> return data;
> +
> + error:
> + virQEMUSaveDataFree(data);
> + return NULL;
> }
>
>
> @@ -2882,9 +2897,15 @@ virQEMUSaveDataWrite(virQEMUSaveDataPtr data,
> {
> virQEMUSaveHeaderPtr header = &data->header;
> size_t len;
> + size_t xml_len;
> + size_t cookie_len = 0;
> int ret = -1;
>
> - len = strlen(data->xml) + 1;
> + xml_len = strlen(data->xml) + 1;
> + if (data->cookie)
> + cookie_len = strlen(data->cookie) + 1;
> +
> + len = xml_len + cookie_len;
>
> if (header->data_len > 0) {
> if (len > header->data_len) {
> @@ -2893,12 +2914,15 @@ virQEMUSaveDataWrite(virQEMUSaveDataPtr data,
> goto cleanup;
> }
>
> - if (VIR_EXPAND_N(data->xml, len, header->data_len - len) < 0)
> + if (VIR_EXPAND_N(data->xml, xml_len, header->data_len - len) < 0)
I think that we should drop the expanding and just write 0 to the
remaining data part of save image ... [1]
> goto cleanup;
> } else {
> header->data_len = len;
> }
>
> + if (data->cookie)
> + header->cookie = xml_len;
and this is also kind of confusing.
> +
> if (safewrite(fd, header, sizeof(*header)) != sizeof(*header)) {
> virReportSystemError(errno,
> _("failed to write header to domain save file '%s'"),
> @@ -2906,13 +2930,21 @@ virQEMUSaveDataWrite(virQEMUSaveDataPtr data,
> goto cleanup;
> }
>
> - if (safewrite(fd, data->xml, header->data_len) != header->data_len) {
> + if (safewrite(fd, data->xml, xml_len) != xml_len) {
> virReportSystemError(errno,
> _("failed to write domain xml to '%s'"),
> path);
> goto cleanup;
[1] ... there you write the expanded XML to the save image which will
stop at the end of the our internal data part ... [2]
> }
>
> + if (data->cookie &&
> + safewrite(fd, data->cookie, cookie_len) != cookie_len) {
> + virReportSystemError(errno,
> + _("failed to write cookie to '%s'"),
> + path);
> + goto cleanup;
> + }
> +
[2] ... and here you continue writing the cookie data out of the
internal data part.
Pavel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: Digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20170606/c615ecaf/attachment-0001.sig>
More information about the libvir-list
mailing list