Commit f7b4a940a430da0e2d48b74e85a8a941c1c2fabc

Authored by aliguori
1 parent fa879c64

snapshot subcommand for qemu-img (Kevin Wolf)

Add snapshot subcommand to qemu-img which allows to list, create, apply
and delete snapshots on qcow2 images.

Signed-off-by: Kevin Wolf <kwolf@suse.de>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>



git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6215 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 2 changed files with 125 additions and 0 deletions
@@ -7,6 +7,10 @@ @@ -7,6 +7,10 @@
7 #include <sys/signal.h> 7 #include <sys/signal.h>
8 #endif 8 #endif
9 9
  10 +#ifndef _WIN32
  11 +#include <sys/time.h>
  12 +#endif
  13 +
10 #ifndef glue 14 #ifndef glue
11 #define xglue(x, y) x ## y 15 #define xglue(x, y) x ## y
12 #define glue(x, y) xglue(x, y) 16 #define glue(x, y) xglue(x, y)
qemu-img.c
@@ -22,6 +22,7 @@ @@ -22,6 +22,7 @@
22 * THE SOFTWARE. 22 * THE SOFTWARE.
23 */ 23 */
24 #include "qemu-common.h" 24 #include "qemu-common.h"
  25 +#include "osdep.h"
25 #include "block_int.h" 26 #include "block_int.h"
26 #include <assert.h> 27 #include <assert.h>
27 28
@@ -60,6 +61,7 @@ static void help(void) @@ -60,6 +61,7 @@ static void help(void)
60 " commit [-f fmt] filename\n" 61 " commit [-f fmt] filename\n"
61 " convert [-c] [-e] [-6] [-f fmt] [-O output_fmt] [-B output_base_image] filename [filename2 [...]] output_filename\n" 62 " convert [-c] [-e] [-6] [-f fmt] [-O output_fmt] [-B output_base_image] filename [filename2 [...]] output_filename\n"
62 " info [-f fmt] filename\n" 63 " info [-f fmt] filename\n"
  64 + " snapshot [-l|-a snapshot|-c snapshot|-d snapshot] filename\n"
63 "\n" 65 "\n"
64 "Command parameters:\n" 66 "Command parameters:\n"
65 " 'filename' is a disk image filename\n" 67 " 'filename' is a disk image filename\n"
@@ -77,6 +79,13 @@ static void help(void) @@ -77,6 +79,13 @@ static void help(void)
77 " '-c' indicates that target image must be compressed (qcow format only)\n" 79 " '-c' indicates that target image must be compressed (qcow format only)\n"
78 " '-e' indicates that the target image must be encrypted (qcow format only)\n" 80 " '-e' indicates that the target image must be encrypted (qcow format only)\n"
79 " '-6' indicates that the target image must use compatibility level 6 (vmdk format only)\n" 81 " '-6' indicates that the target image must use compatibility level 6 (vmdk format only)\n"
  82 + "\n"
  83 + " Parameters to snapshot subcommand:\n"
  84 + " 'snapshot' is the name of the snapshot to create, apply or delete\n"
  85 + " '-a' applies a snapshot (revert disk to saved state)\n"
  86 + " '-c' creates a snapshot\n"
  87 + " '-d' deletes a snapshot\n"
  88 + " '-l' lists all snapshots in the given image\n"
80 ); 89 );
81 printf("\nSupported format:"); 90 printf("\nSupported format:");
82 bdrv_iterate_format(format_print, NULL); 91 bdrv_iterate_format(format_print, NULL);
@@ -732,6 +741,116 @@ static int img_info(int argc, char **argv) @@ -732,6 +741,116 @@ static int img_info(int argc, char **argv)
732 return 0; 741 return 0;
733 } 742 }
734 743
  744 +#define SNAPSHOT_LIST 1
  745 +#define SNAPSHOT_CREATE 2
  746 +#define SNAPSHOT_APPLY 3
  747 +#define SNAPSHOT_DELETE 4
  748 +
  749 +static void img_snapshot(int argc, char **argv)
  750 +{
  751 + BlockDriverState *bs;
  752 + QEMUSnapshotInfo sn;
  753 + char *filename, *snapshot_name = NULL;
  754 + char c;
  755 + int ret;
  756 + int action = 0;
  757 + qemu_timeval tv;
  758 +
  759 + /* Parse commandline parameters */
  760 + for(;;) {
  761 + c = getopt(argc, argv, "la:c:d:h");
  762 + if (c == -1)
  763 + break;
  764 + switch(c) {
  765 + case 'h':
  766 + help();
  767 + return;
  768 + case 'l':
  769 + if (action) {
  770 + help();
  771 + return;
  772 + }
  773 + action = SNAPSHOT_LIST;
  774 + break;
  775 + case 'a':
  776 + if (action) {
  777 + help();
  778 + return;
  779 + }
  780 + action = SNAPSHOT_APPLY;
  781 + snapshot_name = optarg;
  782 + break;
  783 + case 'c':
  784 + if (action) {
  785 + help();
  786 + return;
  787 + }
  788 + action = SNAPSHOT_CREATE;
  789 + snapshot_name = optarg;
  790 + break;
  791 + case 'd':
  792 + if (action) {
  793 + help();
  794 + return;
  795 + }
  796 + action = SNAPSHOT_DELETE;
  797 + snapshot_name = optarg;
  798 + break;
  799 + }
  800 + }
  801 +
  802 + if (optind >= argc)
  803 + help();
  804 + filename = argv[optind++];
  805 +
  806 + /* Open the image */
  807 + bs = bdrv_new("");
  808 + if (!bs)
  809 + error("Not enough memory");
  810 +
  811 + if (bdrv_open2(bs, filename, 0, NULL) < 0) {
  812 + error("Could not open '%s'", filename);
  813 + }
  814 +
  815 + /* Perform the requested action */
  816 + switch(action) {
  817 + case SNAPSHOT_LIST:
  818 + dump_snapshots(bs);
  819 + break;
  820 +
  821 + case SNAPSHOT_CREATE:
  822 + memset(&sn, 0, sizeof(sn));
  823 + pstrcpy(sn.name, sizeof(sn.name), snapshot_name);
  824 +
  825 + qemu_gettimeofday(&tv);
  826 + sn.date_sec = tv.tv_sec;
  827 + sn.date_nsec = tv.tv_usec * 1000;
  828 +
  829 + ret = bdrv_snapshot_create(bs, &sn);
  830 + if (ret)
  831 + error("Could not create snapshot '%s': %d (%s)",
  832 + snapshot_name, ret, strerror(-ret));
  833 + break;
  834 +
  835 + case SNAPSHOT_APPLY:
  836 + ret = bdrv_snapshot_goto(bs, snapshot_name);
  837 + if (ret)
  838 + error("Could not apply snapshot '%s': %d (%s)",
  839 + snapshot_name, ret, strerror(-ret));
  840 + break;
  841 +
  842 + case SNAPSHOT_DELETE:
  843 + ret = bdrv_snapshot_delete(bs, snapshot_name);
  844 + if (ret)
  845 + error("Could not delete snapshot '%s': %d (%s)",
  846 + snapshot_name, ret, strerror(-ret));
  847 + break;
  848 + }
  849 +
  850 + /* Cleanup */
  851 + bdrv_delete(bs);
  852 +}
  853 +
735 int main(int argc, char **argv) 854 int main(int argc, char **argv)
736 { 855 {
737 const char *cmd; 856 const char *cmd;
@@ -749,6 +868,8 @@ int main(int argc, char **argv) @@ -749,6 +868,8 @@ int main(int argc, char **argv)
749 img_convert(argc, argv); 868 img_convert(argc, argv);
750 } else if (!strcmp(cmd, "info")) { 869 } else if (!strcmp(cmd, "info")) {
751 img_info(argc, argv); 870 img_info(argc, argv);
  871 + } else if (!strcmp(cmd, "snapshot")) {
  872 + img_snapshot(argc, argv);
752 } else { 873 } else {
753 help(); 874 help();
754 } 875 }