[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH 19/16] save: add virsh commands for manipulating save files



Now you can edit a saved state file even if you forgot to grab
a dumpxml file prior to saving a domain.  Plus, in-place editing
feels so much nicer.

* tools/virsh.c (cmdSaveImageDumpxml, cmdSaveImageDefine)
(cmdSaveImageEdit): New commands.
* tools/virsh.pod (save-image-dumpxml, save-image-define)
(save-image-edit): Document them.
---

Needs the next patch to be testable.  'save-image-edit' feels a bit
long, but I couldn't think of something shorter.  Should I keep the
new save-image-* commands in the main domain group, or should I create
a new save-image group, in case we add more later?

 tools/virsh.c   |  178 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 tools/virsh.pod |   31 ++++++++++
 2 files changed, 209 insertions(+), 0 deletions(-)

diff --git a/tools/virsh.c b/tools/virsh.c
index dece917..1701f09 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -1659,6 +1659,178 @@ cleanup:
 }

 /*
+ * "save-image-dumpxml" command
+ */
+static const vshCmdInfo info_save_image_dumpxml[] = {
+    {"help", N_("saved state domain information in XML")},
+    {"desc", N_("Output the domain information for a saved state file,\n"
+                "as an XML dump to stdout.")},
+    {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_save_image_dumpxml[] = {
+    {"file", VSH_OT_DATA, VSH_OFLAG_REQ, N_("saved state file to read")},
+    {"security-info", VSH_OT_BOOL, 0, N_("include security sensitive information in XML dump")},
+    {NULL, 0, 0, NULL}
+};
+
+static bool
+cmdSaveImageDumpxml(vshControl *ctl, const vshCmd *cmd)
+{
+    const char *file = NULL;
+    bool ret = false;
+    int flags = 0;
+    char *xml = NULL;
+
+    if (vshCommandOptBool(cmd, "security-info"))
+        flags |= VIR_DOMAIN_XML_SECURE;
+
+    if (!vshConnectionUsability(ctl, ctl->conn))
+        return false;
+
+    if (vshCommandOptString(cmd, "file", &file) <= 0)
+        return false;
+
+    xml = virDomainSaveImageGetXMLDesc(ctl->conn, file, flags);
+    if (!xml)
+        goto cleanup;
+
+    vshPrint(ctl, "%s", xml);
+    ret = true;
+
+cleanup:
+    VIR_FREE(xml);
+    return ret;
+}
+
+/*
+ * "save-image-define" command
+ */
+static const vshCmdInfo info_save_image_define[] = {
+    {"help", N_("redefine the XML for a domain's saved state file")},
+    {"desc", N_("Replace the domain XML associated with a saved state file")},
+    {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_save_image_define[] = {
+    {"file", VSH_OT_DATA, VSH_OFLAG_REQ, N_("saved state file to modify")},
+    {"xml", VSH_OT_STRING, VSH_OFLAG_REQ,
+     N_("filename containing updated XML for the target")},
+    {NULL, 0, 0, NULL}
+};
+
+static bool
+cmdSaveImageDefine(vshControl *ctl, const vshCmd *cmd)
+{
+    const char *file = NULL;
+    bool ret = false;
+    const char *xmlfile = NULL;
+    char *xml = NULL;
+
+    if (!vshConnectionUsability(ctl, ctl->conn))
+        return false;
+
+    if (vshCommandOptString(cmd, "file", &file) <= 0)
+        return false;
+
+    if (vshCommandOptString(cmd, "xml", &xmlfile) <= 0) {
+        vshError(ctl, "%s", _("malformed or missing xml argument"));
+        return false;
+    }
+
+    if (virFileReadAll(xmlfile, 8192, &xml) < 0)
+        goto cleanup;
+
+    if (virDomainSaveImageDefineXML(ctl->conn, file, xml, 0) < 0) {
+        vshError(ctl, _("Failed to update %s"), file);
+        goto cleanup;
+    }
+
+    vshPrint(ctl, _("State file %s updated.\n"), file);
+    ret = true;
+
+cleanup:
+    VIR_FREE(xml);
+    return ret;
+}
+
+/*
+ * "save-image-edit" command
+ */
+static const vshCmdInfo info_save_image_edit[] = {
+    {"help", N_("edit XML for a domain's saved state file")},
+    {"desc", N_("Edit the domain XML associated with a saved state file")},
+    {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_save_image_edit[] = {
+    {"file", VSH_OT_DATA, VSH_OFLAG_REQ, N_("saved state file to edit")},
+    {NULL, 0, 0, NULL}
+};
+
+static bool
+cmdSaveImageEdit(vshControl *ctl, const vshCmd *cmd)
+{
+    const char *file = NULL;
+    bool ret = false;
+    char *tmp = NULL;
+    char *doc = NULL;
+    char *doc_edited = NULL;
+    int flags = VIR_DOMAIN_XML_SECURE;
+
+    if (!vshConnectionUsability(ctl, ctl->conn))
+        return false;
+
+    if (vshCommandOptString(cmd, "file", &file) <= 0)
+        return false;
+
+    /* Get the XML configuration of the saved image.  */
+    doc = virDomainSaveImageGetXMLDesc(ctl->conn, file, flags);
+    if (!doc)
+        goto cleanup;
+
+    /* Create and open the temporary file.  */
+    tmp = editWriteToTempFile(ctl, doc);
+    if (!tmp)
+        goto cleanup;
+
+    /* Start the editor.  */
+    if (editFile(ctl, tmp) == -1)
+        goto cleanup;
+
+    /* Read back the edited file.  */
+    doc_edited = editReadBackFile(ctl, tmp);
+    if (!doc_edited)
+        goto cleanup;
+
+    /* Compare original XML with edited.  Has it changed at all?  */
+    if (STREQ(doc, doc_edited)) {
+        vshPrint(ctl, _("Saved image %s XML configuration not changed.\n"),
+                 file);
+        ret = true;
+        goto cleanup;
+    }
+
+    /* Everything checks out, so redefine the xml.  */
+    if (virDomainSaveImageDefineXML(ctl->conn, file, doc_edited, 0) < 0) {
+        vshError(ctl, _("Failed to update %s"), file);
+        goto cleanup;
+    }
+
+    vshPrint(ctl, _("State file %s edited.\n"), file);
+    ret = true;
+
+cleanup:
+    VIR_FREE(doc);
+    VIR_FREE(doc_edited);
+    if (tmp) {
+        unlink(tmp);
+        VIR_FREE(tmp);
+    }
+    return ret;
+}
+
+/*
  * "managedsave" command
  */
 static const vshCmdInfo info_managedsave[] = {
@@ -12084,6 +12256,12 @@ static const vshCmdDef domManagementCmds[] = {
     {"restore", cmdRestore, opts_restore, info_restore, 0},
     {"resume", cmdResume, opts_resume, info_resume, 0},
     {"save", cmdSave, opts_save, info_save, 0},
+    {"save-image-define", cmdSaveImageDefine, opts_save_image_define,
+     info_save_image_define, 0},
+    {"save-image-dumpxml", cmdSaveImageDumpxml, opts_save_image_dumpxml,
+     info_save_image_dumpxml, 0},
+    {"save-image-edit", cmdSaveImageEdit, opts_save_image_edit,
+     info_save_image_edit, 0},
     {"schedinfo", cmdSchedinfo, opts_schedinfo, info_schedinfo, 0},
     {"screenshot", cmdScreenshot, opts_screenshot, info_screenshot, 0},
     {"setmaxmem", cmdSetmaxmem, opts_setmaxmem, info_setmaxmem, 0},
diff --git a/tools/virsh.pod b/tools/virsh.pod
index f2fd9ed..b31d374 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -642,6 +642,37 @@ between the creation and restore point.  For a more complete system
 restore point, where the disk state is saved alongside the memory
 state, see the B<snapshot> family of commands.

+=item B<save-image-define> I<file> I<xml>
+
+Update the domain XML that will be used when I<file> is later
+used in the B<restore> command.  The I<xml> argument must be a file
+name containing the alternative XML, with changes only in the
+host-specific portions of the domain XML.  For example, it can
+be used to account for file naming differences resulting from creating
+disk snapshots of underlying storage after the guest was saved.
+
+=item B<save-image-dumpxml> I<file> [I<--security-info>]
+
+Extract the domain XML that was in effect at the time the saved state
+file I<file> was created with the B<save> command.  Using
+I<--security-info> will also include security sensitive information.
+
+=item B<save-image-edit> I<file>
+
+Edit the XML configuration associated with a saved state file I<file>
+created by the B<save> command.
+
+This is equivalent to:
+
+ virsh save-image-dumpxml state-file > state-file.xml
+ vi state-file.xml (or make changes with your other text editor)
+ virsh save-image-define state-file state-file-xml
+
+except that it does some error checking.
+
+The editor used can be supplied by the C<$VISUAL> or C<$EDITOR> environment
+variables, and defaults to C<vi>.
+
 =item B<schedinfo> [I<--set> B<parameter=value>] I<domain-id> [[I<--config>]
 [I<--live>] | [I<--current>]]

-- 
1.7.4.4


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]