[libvirt] [PATCH 4/4] New virsh commands to manage saved-state and core-dump files

Hong Xiang hxiang at linux.vnet.ibm.com
Tue Oct 25 07:44:39 UTC 2011


New virsh commands:
. save-image-list
. save-image-remove <file>
. save-image-download <file> <local-file>
. dump-list
. dump-remove <file>
. dump-download <file> <local-file>

* tools/virsh.c: new commands implementations

Signed-off-by: Hong Xiang <hxiang at linux.vnet.ibm.com>
---
 tools/virsh.c |  309 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 309 insertions(+), 0 deletions(-)

diff --git a/tools/virsh.c b/tools/virsh.c
index 72344f0..a1cafbe 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -300,6 +300,8 @@ static int vshCommandOptULongLong(const vshCmd *cmd, const char *name,
 static bool vshCommandOptBool(const vshCmd *cmd, const char *name);
 static const vshCmdOpt *vshCommandOptArgv(const vshCmd *cmd,
                                           const vshCmdOpt *opt);
+static int vshStreamSink(virStreamPtr st ATTRIBUTE_UNUSED,
+                         const char *bytes, size_t nbytes, void *opaque);
 
 #define VSH_BYID     (1 << 1)
 #define VSH_BYUUID   (1 << 2)
@@ -2445,6 +2447,155 @@ cleanup:
 }
 
 /*
+ * "save-image-list" command
+ */
+static const vshCmdInfo info_save_image_list[] = {
+    {"help", N_("list saved state files")},
+    {"desc", N_("Output the list of saved state files.\n")},
+    {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_save_image_list[] = {
+    {NULL, 0, 0, NULL}
+};
+
+static bool
+cmdSaveImageList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
+{
+    int maxfiles = 0, i;
+    char ** files = NULL;
+
+    if (!vshConnectionUsability(ctl, ctl->conn))
+        return false;
+
+    if(0 > (maxfiles = virConnectNumOfSavedImages(ctl->conn))) {
+        vshError(ctl, "%s", _("Failed to list saved state files"));
+        return false;
+    }
+    if(maxfiles) {
+        files = vshMalloc(ctl, sizeof(char *) * maxfiles);
+        if(0 > (maxfiles = virConnectListSavedImages(ctl->conn, files,
+                                                   maxfiles))) {
+            vshError(ctl, "%s", _("Failed to list saved state files"));
+            VIR_FREE(files);
+            return false;
+        }
+        qsort(files, maxfiles, sizeof(char *), namesorter);
+    }
+    for(i = 0; i < maxfiles; i ++) {
+        vshPrint(ctl, "%s\n", files[i]);
+        VIR_FREE(files[i]);
+    }
+
+    VIR_FREE(files);
+    return true;
+}
+
+/*
+ * "save-image-remove" command
+ */
+static const vshCmdInfo info_save_image_remove[] = {
+    {"help", N_("remove a saved state file")},
+    {"desc", N_("Remove the specified saved state file")},
+    {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_save_image_remove[] = {
+    {"file", VSH_OT_DATA, VSH_OFLAG_REQ, N_("saved state file to remove")},
+    {NULL, 0, 0, NULL}
+};
+
+static bool
+cmdSaveImageRemove(vshControl *ctl, const vshCmd *cmd)
+{
+    const char *file = NULL;
+
+    if (!vshConnectionUsability(ctl, ctl->conn))
+        return false;
+
+    if (vshCommandOptString(cmd, "file", &file) <= 0)
+        return false;
+
+    if(virSavedImageRemove(ctl->conn, file)) {
+        vshPrint(ctl, _("Failed to remove saved state file '%s'.\n"),
+                 file);
+        return false;
+    }
+
+    return true;
+}
+
+/*
+ * "save-image-download" command
+ */
+static const vshCmdInfo info_save_image_download[] = {
+    {"help", N_("download a saved state file to local")},
+    {"desc", N_("Download the specified saved state file to local.")},
+    {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_save_image_download[] = {
+    {"file", VSH_OT_DATA, VSH_OFLAG_REQ, N_("saved state file to download")},
+    {"local-file", VSH_OT_DATA, VSH_OFLAG_REQ, N_("local file")},
+    {NULL, 0, 0, NULL}
+};
+
+static bool
+cmdSaveImageDownload(vshControl *ctl, const vshCmd *cmd)
+{
+    const char *file = NULL;
+    const char *local_file = NULL;
+    bool ret = false;
+    int fd = -1;
+    virStreamPtr stream = NULL;
+
+    if (!vshConnectionUsability(ctl, ctl->conn))
+        return false;
+
+    if (vshCommandOptString(cmd, "file", &file) <= 0)
+        return false;
+    if (vshCommandOptString(cmd, "local-file", &local_file) <= 0)
+        return false;
+
+    if (0 > (fd = open(local_file, O_WRONLY | O_CREAT | O_TRUNC, 0666))) {
+        vshError(ctl, _("cannot open file %s"), local_file);
+        goto cleanup;
+    }
+    if (NULL == (stream = virStreamNew(ctl->conn, 0))) {
+        vshError(ctl, _("cannot open stream"));
+        goto cleanup;
+    }
+    if (0 > virSavedImageDownload(ctl->conn, stream, file)) {
+        vshError(ctl, _("cannot download saved state file %s"), file);
+        goto cleanup;
+    }
+    if (0 > virStreamRecvAll(stream, vshStreamSink, &fd)) {
+        vshError(ctl, _("cannot receive data from saved state file %s"), file);
+        goto cleanup;
+    }
+
+    if (0 > VIR_CLOSE(fd)) {
+        vshError(ctl, _("cannot close file %s"), local_file);
+        virStreamAbort(stream);
+        goto cleanup;
+    }
+    if (0 > virStreamFinish(stream)) {
+        vshError(ctl, _("cannot close saved state file %s"), file);
+        goto cleanup;
+    }
+
+    ret = true;
+
+cleanup:
+    VIR_FORCE_CLOSE(fd);
+    if(!ret)
+        ignore_value(unlink(local_file));
+    if(stream)
+        virStreamFree(stream);
+    return ret;
+}
+
+/*
  * "managedsave" command
  */
 static const vshCmdInfo info_managedsave[] = {
@@ -2935,6 +3086,155 @@ cleanup:
     return ret;
 }
 
+/*
+ * "dump-list" command
+ */
+static const vshCmdInfo info_dump_list[] = {
+    {"help", N_("list core dump files")},
+    {"desc", N_("Output the list of core dump files.\n")},
+    {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_dump_list[] = {
+    {NULL, 0, 0, NULL}
+};
+
+static bool
+cmdDumpList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
+{
+    int maxfiles = 0, i;
+    char ** files = NULL;
+
+    if (!vshConnectionUsability(ctl, ctl->conn))
+        return false;
+
+    if(0 > (maxfiles = virConnectNumOfCoreDumps(ctl->conn))) {
+        vshError(ctl, "%s", _("Failed to list core dump files"));
+        return false;
+    }
+    if(maxfiles) {
+        files = vshMalloc(ctl, sizeof(char *) * maxfiles);
+        if(0 > (maxfiles = virConnectListCoreDumps(ctl->conn, files,
+                                                   maxfiles))) {
+            vshError(ctl, "%s", _("Failed to list core dump files"));
+            VIR_FREE(files);
+            return false;
+        }
+        qsort(files, maxfiles, sizeof(char *), namesorter);
+    }
+    for(i = 0; i < maxfiles; i ++) {
+        vshPrint(ctl, "%s\n", files[i]);
+        VIR_FREE(files[i]);
+    }
+
+    VIR_FREE(files);
+    return true;
+}
+
+/*
+ * "dump-remove" command
+ */
+static const vshCmdInfo info_dump_remove[] = {
+    {"help", N_("remove a core dump file")},
+    {"desc", N_("Remove the specified core dump file")},
+    {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_dump_remove[] = {
+    {"file", VSH_OT_DATA, VSH_OFLAG_REQ, N_("core dump file to remove")},
+    {NULL, 0, 0, NULL}
+};
+
+static bool
+cmdDumpRemove(vshControl *ctl, const vshCmd *cmd)
+{
+    const char *file = NULL;
+
+    if (!vshConnectionUsability(ctl, ctl->conn))
+        return false;
+
+    if (vshCommandOptString(cmd, "file", &file) <= 0)
+        return false;
+
+    if(virCoreDumpRemove(ctl->conn, file)) {
+        vshPrint(ctl, _("Failed to remove core dump file %s.\n"),
+                 file);
+        return false;
+    }
+
+    return true;
+}
+
+/*
+ * "dump-download" command
+ */
+static const vshCmdInfo info_dump_download[] = {
+    {"help", N_("download a core dump file to local")},
+    {"desc", N_("Download the specified core dump file to local.")},
+    {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_dump_download[] = {
+    {"file", VSH_OT_DATA, VSH_OFLAG_REQ, N_("core dump file to download")},
+    {"local-file", VSH_OT_DATA, VSH_OFLAG_REQ, N_("local file")},
+    {NULL, 0, 0, NULL}
+};
+
+static bool
+cmdDumpDownload(vshControl *ctl, const vshCmd *cmd)
+{
+    const char *file = NULL;
+    const char *local_file = NULL;
+    bool ret = false;
+    int fd = -1;
+    virStreamPtr stream = NULL;
+
+    if (!vshConnectionUsability(ctl, ctl->conn))
+        return false;
+
+    if (vshCommandOptString(cmd, "file", &file) <= 0)
+        return false;
+    if (vshCommandOptString(cmd, "local-file", &local_file) <= 0)
+        return false;
+
+    if (0 > (fd = open(local_file, O_WRONLY | O_CREAT | O_TRUNC, 0666))) {
+        vshError(ctl, _("cannot open file %s"), local_file);
+        goto cleanup;
+    }
+    if(NULL == (stream = virStreamNew(ctl->conn, 0))) {
+        vshError(ctl, _("cannot open stream"));
+        goto cleanup;
+    }
+    if (0 > virCoreDumpDownload(ctl->conn, stream, file)) {
+        vshError(ctl, _("cannot download core dump file %s"), file);
+        goto cleanup;
+    }
+    if (0 > virStreamRecvAll(stream, vshStreamSink, &fd)) {
+        vshError(ctl, _("cannot receive data from core dump file %s"), file);
+        goto cleanup;
+    }
+
+    if (0 > VIR_CLOSE(fd)) {
+        vshError(ctl, _("cannot close file %s"), local_file);
+        virStreamAbort(stream);
+        goto cleanup;
+    }
+    if (0 > virStreamFinish(stream)) {
+        vshError(ctl, _("cannot close core dump file %s"), file);
+        goto cleanup;
+    }
+
+    ret = true;
+
+cleanup:
+    VIR_FORCE_CLOSE(fd);
+    if(!ret)
+        ignore_value(unlink(local_file));
+    if(stream)
+        virStreamFree(stream);
+    return ret;
+}
+
 static const vshCmdInfo info_screenshot[] = {
     {"help", N_("take a screenshot of a current domain console and store it "
                 "into a file")},
@@ -14041,6 +14341,9 @@ static const vshCmdDef domManagementCmds[] = {
     {"domxml-to-native", cmdDomXMLToNative, opts_domxmltonative,
      info_domxmltonative, 0},
     {"dump", cmdDump, opts_dump, info_dump, 0},
+    {"dump-list", cmdDumpList, opts_dump_list, info_dump_list, 0},
+    {"dump-remove", cmdDumpRemove, opts_dump_remove, info_dump_remove, 0},
+    {"dump-download", cmdDumpDownload, opts_dump_download, info_dump_download, 0},
     {"dumpxml", cmdDumpXML, opts_dumpxml, info_dumpxml, 0},
     {"edit", cmdEdit, opts_edit, info_edit, 0},
     {"inject-nmi", cmdInjectNMI, opts_inject_nmi, info_inject_nmi, 0},
@@ -14068,6 +14371,12 @@ static const vshCmdDef domManagementCmds[] = {
      info_save_image_dumpxml, 0},
     {"save-image-edit", cmdSaveImageEdit, opts_save_image_edit,
      info_save_image_edit, 0},
+    {"save-image-list", cmdSaveImageList, opts_save_image_list,
+     info_save_image_list, 0},
+    {"save-image-remove", cmdSaveImageRemove, opts_save_image_remove,
+     info_save_image_remove, 0},
+    {"save-image-download", cmdSaveImageDownload, opts_save_image_download,
+     info_save_image_download, 0},
     {"schedinfo", cmdSchedinfo, opts_schedinfo, info_schedinfo, 0},
     {"screenshot", cmdScreenshot, opts_screenshot, info_screenshot, 0},
     {"setmaxmem", cmdSetmaxmem, opts_setmaxmem, info_setmaxmem, 0},
-- 
1.7.1




More information about the libvir-list mailing list