From 38149ec145416fe15ba662e9083af1e5b941a2e9 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Tue, 19 Jul 2011 14:24:29 -0600 Subject: [PATCH] save: support --xml to virsh save/restore Also, migrate was missing documentation for the --xml option added in commit ec5301cb. * tools/virsh.c (cmdSave, cmdRestore): Add xml argument. * tools/virsh.pod (save, restore, migrate): Document it. --- tools/virsh.c | 34 ++++++++++++++++++++++++++++++++-- tools/virsh.pod | 24 ++++++++++++++++++++---- 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index e9c37c43ce..39492f5104 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -1606,6 +1606,8 @@ static const vshCmdOptDef opts_save[] = { {"bypass-cache", VSH_OT_BOOL, 0, N_("avoid file system cache when saving")}, {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")}, {"file", VSH_OT_DATA, VSH_OFLAG_REQ, N_("where to save the data")}, + {"xml", VSH_OT_STRING, 0, + N_("filename containing updated XML for the target")}, {NULL, 0, 0, NULL} }; @@ -1617,6 +1619,8 @@ cmdSave(vshControl *ctl, const vshCmd *cmd) const char *to = NULL; bool ret = false; int flags = 0; + const char *xmlfile = NULL; + char *xml = NULL; if (!vshConnectionUsability(ctl, ctl->conn)) return false; @@ -1627,10 +1631,20 @@ cmdSave(vshControl *ctl, const vshCmd *cmd) if (vshCommandOptBool(cmd, "bypass-cache")) flags |= VIR_DOMAIN_SAVE_BYPASS_CACHE; + if (vshCommandOptString(cmd, "xml", &xmlfile) < 0) { + vshError(ctl, "%s", _("malformed xml argument")); + return false; + } + if (!(dom = vshCommandOptDomain(ctl, cmd, &name))) return false; - if ((flags ? virDomainSaveFlags(dom, to, NULL, flags) + if (xmlfile && + virFileReadAll(xmlfile, 8192, &xml) < 0) + goto cleanup; + + if (((flags || xml) + ? virDomainSaveFlags(dom, to, xml, flags) : virDomainSave(dom, to)) < 0) { vshError(ctl, _("Failed to save domain %s to %s"), name, to); goto cleanup; @@ -1640,6 +1654,7 @@ cmdSave(vshControl *ctl, const vshCmd *cmd) ret = true; cleanup: + VIR_FREE(xml); virDomainFree(dom); return ret; } @@ -2016,6 +2031,8 @@ static const vshCmdOptDef opts_restore[] = { {"file", VSH_OT_DATA, VSH_OFLAG_REQ, N_("the state to restore")}, {"bypass-cache", VSH_OT_BOOL, 0, N_("avoid file system cache when restoring")}, + {"xml", VSH_OT_STRING, 0, + N_("filename containing updated XML for the target")}, {NULL, 0, 0, NULL} }; @@ -2025,6 +2042,8 @@ cmdRestore(vshControl *ctl, const vshCmd *cmd) const char *from = NULL; bool ret = false; int flags = 0; + const char *xmlfile = NULL; + char *xml = NULL; if (!vshConnectionUsability(ctl, ctl->conn)) return false; @@ -2035,7 +2054,17 @@ cmdRestore(vshControl *ctl, const vshCmd *cmd) if (vshCommandOptBool(cmd, "bypass-cache")) flags |= VIR_DOMAIN_SAVE_BYPASS_CACHE; - if ((flags ? virDomainRestoreFlags(ctl->conn, from, NULL, flags) + if (vshCommandOptString(cmd, "xml", &xmlfile) < 0) { + vshError(ctl, "%s", _("malformed xml argument")); + return false; + } + + if (xmlfile && + virFileReadAll(xmlfile, 8192, &xml) < 0) + goto cleanup; + + if (((flags || xml) + ? virDomainRestoreFlags(ctl->conn, from, xml, flags) : virDomainRestore(ctl->conn, from)) < 0) { vshError(ctl, _("Failed to restore domain from %s"), from); goto cleanup; @@ -2045,6 +2074,7 @@ cmdRestore(vshControl *ctl, const vshCmd *cmd) ret = true; cleanup: + VIR_FREE(xml); return ret; } diff --git a/tools/virsh.pod b/tools/virsh.pod index 1f52da8328..0459324d78 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -544,7 +544,7 @@ type attribute for the element of XML. =item B [I<--live>] [I<--direct>] [I<--p2p> [I<--tunnelled>]] [I<--persistent>] [I<--undefinesource>] [I<--suspend>] [I<--copy-storage-all>] [I<--copy-storage-inc>] [I<--verbose>] I I [I] -[I] [I<--timeout> B] +[I] [I<--timeout> B] [I<--xml> B] Migrate domain to another host. Add I<--live> for live migration; I<--p2p> for peer-2-peer migration; I<--direct> for direct migration; or I<--tunnelled> @@ -559,7 +559,11 @@ I<--verbose> displays the progress of migration. The I is the connection URI of the destination host, and I is the migration URI, which usually can be omitted. I is used for renaming the domain to new name during migration, which -also usually can be omitted. +also usually can be omitted. Likewise, I<--xml> B is usually +omitted, but can be used to supply an alternative XML file for use on +the destination to supply a larger set of changes to any host-specific +portions of the domain XML, such as accounting for naming differences +between source and destination in accessing underlying storage. I<--timeout> B forces guest to suspend when live migration exceeds that many seconds, and @@ -599,19 +603,25 @@ domain actually reboots. The exact behavior of a domain when it reboots is set by the I parameter in the domain's XML definition. -=item B I [I<--bypass-cache>] +=item B I [I<--bypass-cache>] [I<--xml> B] Restores a domain from a B state file. See I for more info. If I<--bypass-cache> is specified, the restore will avoid the file system cache, although this may slow down the operation. +I<--xml> B is usually omitted, but can be used to supply an +alternative XML file for use on the restored guest with changes only +in the host-specific portions of the domain XML. For example, it can +be used to account for file naming differences in underlying storage +due to disk snapshots taken after the guest was saved. + B: To avoid corrupting file system contents within the domain, you should not reuse the saved state file for a second B unless you have also reverted all storage volumes back to the same contents as when the state file was created. -=item B I I [I<--bypass-cache>] +=item B I I [I<--bypass-cache>] [I<--xml> B] Saves a running domain (RAM, but not disk state) to a state file so that it can be restored @@ -625,6 +635,12 @@ This is roughly equivalent to doing a hibernate on a running computer, with all the same limitations. Open network connections may be severed upon restore, as TCP timeouts may have expired. +I<--xml> B is usually omitted, but can be used to supply an +alternative XML file for use on the restored guest with changes only +in the host-specific portions of the domain XML. For example, it can +be used to account for file naming differences that are planned to +be made via disk snapshots of underlying storage after the guest is saved. + Domain saved state files assume that disk images will be unchanged between the creation and restore point. For a more complete system restore point, where the disk state is saved alongside the memory