]> git.proxmox.com Git - pve-qemu-kvm.git/commitdiff
implement loadstate - cleanup snapshot patches
authorDietmar Maurer <dietmar@proxmox.com>
Tue, 18 Sep 2012 06:57:12 +0000 (08:57 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Tue, 18 Sep 2012 06:57:12 +0000 (08:57 +0200)
debian/patches/implement-qemu-fopen-bdrv.patch [new file with mode: 0644]
debian/patches/internal-snapshot.patch
debian/patches/load-state-from-blockdev.patch [new file with mode: 0644]
debian/patches/move-bdrv-snapshot-find.patch [new file with mode: 0644]
debian/patches/series

diff --git a/debian/patches/implement-qemu-fopen-bdrv.patch b/debian/patches/implement-qemu-fopen-bdrv.patch
new file mode 100644 (file)
index 0000000..1e6e5f6
--- /dev/null
@@ -0,0 +1,90 @@
+Index: new/savevm.c
+===================================================================
+--- new.orig/savevm.c  2012-09-18 07:05:08.000000000 +0200
++++ new/savevm.c       2012-09-18 07:19:31.000000000 +0200
+@@ -387,29 +387,48 @@
+     return NULL;
+ }
+-static int block_put_buffer(void *opaque, const uint8_t *buf,
++static int block_state_put_buffer(void *opaque, const uint8_t *buf,
+                            int64_t pos, int size)
+ {
+-    bdrv_save_vmstate(opaque, buf, pos, size);
+-    return size;
++    return bdrv_save_vmstate(opaque, buf, pos, size);
+ }
+-static int block_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
++static int block_state_get_buffer(void *opaque, uint8_t *buf, int64_t pos,
++                                  int size)
+ {
+     return bdrv_load_vmstate(opaque, buf, pos, size);
+ }
++static int block_put_buffer(void *opaque, const uint8_t *buf, int64_t pos,
++                            int size)
++{
++    return bdrv_pwrite(opaque, pos, buf, size);
++}
++
++static int block_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
++{
++    return bdrv_pread(opaque, pos, buf, size);
++}
++
+ static int bdrv_fclose(void *opaque)
+ {
+     return bdrv_flush(opaque);
+ }
+-static QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int is_writable)
++QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int is_writable)
++{
++    return qemu_fopen_ops(bs, is_writable ? block_put_buffer : NULL,
++                          block_get_buffer, bdrv_fclose,
++                          NULL, NULL, NULL);
++}
++
++static QEMUFile *qemu_fopen_bdrv_state(BlockDriverState *bs, int is_writable)
+ {
+     if (is_writable)
+-        return qemu_fopen_ops(bs, block_put_buffer, NULL, bdrv_fclose, 
++        return qemu_fopen_ops(bs, block_state_put_buffer, NULL, bdrv_fclose,
+                             NULL, NULL, NULL);
+-    return qemu_fopen_ops(bs, NULL, block_get_buffer, bdrv_fclose, NULL, NULL, NULL);
++    return qemu_fopen_ops(bs, NULL, block_state_get_buffer, bdrv_fclose,
++                          NULL, NULL, NULL);
+ }
+ QEMUFile *qemu_fopen_ops(void *opaque, QEMUFilePutBufferFunc *put_buffer,
+@@ -2145,7 +2164,7 @@
+     }
+     /* save the VM state */
+-    f = qemu_fopen_bdrv(bs, 1);
++    f = qemu_fopen_bdrv_state(bs, 1);
+     if (!f) {
+         monitor_printf(mon, "Could not open VM state file\n");
+         goto the_end;
+@@ -2266,7 +2285,7 @@
+     }
+     /* restore the VM state */
+-    f = qemu_fopen_bdrv(bs_vm_state, 0);
++    f = qemu_fopen_bdrv_state(bs_vm_state, 0);
+     if (!f) {
+         error_report("Could not open VM state file");
+         return -EINVAL;
+Index: new/qemu-file.h
+===================================================================
+--- new.orig/qemu-file.h       2012-09-18 07:05:08.000000000 +0200
++++ new/qemu-file.h    2012-09-18 07:07:26.000000000 +0200
+@@ -68,6 +68,7 @@
+ QEMUFile *qemu_fopen(const char *filename, const char *mode);
+ QEMUFile *qemu_fdopen(int fd, const char *mode);
+ QEMUFile *qemu_fopen_socket(int fd);
++QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int is_writable);
+ QEMUFile *qemu_popen(FILE *popen_file, const char *mode);
+ QEMUFile *qemu_popen_cmd(const char *command, const char *mode);
+ int qemu_stdio_fd(QEMUFile *f);
index f88af282d6a86046c5fc406cd3773470451fee3e..77f0338d3fd687e57fea3b2a61333ef7d81f4010 100644 (file)
@@ -1,7 +1,7 @@
 Index: new/qapi-schema.json
 ===================================================================
---- new.orig/qapi-schema.json  2012-09-07 07:41:45.000000000 +0200
-+++ new/qapi-schema.json       2012-09-13 09:22:06.000000000 +0200
+--- new.orig/qapi-schema.json  2012-09-18 06:20:41.000000000 +0200
++++ new/qapi-schema.json       2012-09-18 08:43:25.000000000 +0200
 @@ -2493,3 +2493,12 @@
  # Since: 1.2.0
  ##
@@ -17,237 +17,206 @@ Index: new/qapi-schema.json
 +{ 'command': 'snapshot-end' }
 Index: new/qmp.c
 ===================================================================
---- new.orig/qmp.c     2012-09-07 07:41:45.000000000 +0200
-+++ new/qmp.c  2012-09-14 14:06:56.000000000 +0200
-@@ -479,3 +479,224 @@
+--- new.orig/qmp.c     2012-09-18 06:20:41.000000000 +0200
++++ new/qmp.c  2012-09-18 08:54:54.000000000 +0200
+@@ -479,3 +479,193 @@
      return arch_query_cpu_definitions(errp);
  }
  
 +static struct SnapshotState {
-+      int in_progress;
-+      int saved_vm_running;
++    int in_progress;
++    int saved_vm_running;
 +} snap_state;
 +
-+static int block_put_buffer(void *opaque, const uint8_t *buf,
-+                           int64_t pos, int size)
-+{
-+      bdrv_pwrite(opaque, pos, buf, size);
-+      return size;
-+}
-+
-+static int bdrv_fclose(void *opaque)
-+{
-+      return bdrv_flush(opaque);
-+}
-+
 +void qmp_snapshot_start(bool has_statefile, const char *statefile, Error **errp)
 +{
-+      BlockDriverState *bs = NULL;
-+      BlockDriver *drv = NULL;
-+      int bdrv_oflags = BDRV_O_NOCACHE | BDRV_O_RDWR;
-+      QEMUFile *f;
-+      int ret;
-+
-+      if (snap_state.in_progress) {
-+              error_set(errp, ERROR_CLASS_GENERIC_ERROR,
-+                        "VM snapshot already started\n");
-+              return;
-+      }
-+
-+      snap_state.in_progress = 1;
++    BlockDriverState *bs = NULL;
++    BlockDriver *drv = NULL;
++    int bdrv_oflags = BDRV_O_NOCACHE | BDRV_O_RDWR;
++    QEMUFile *f;
++    int ret;
++
++    if (snap_state.in_progress) {
++        error_set(errp, ERROR_CLASS_GENERIC_ERROR,
++                  "VM snapshot already started\n");
++        return;
++    }
 +
-+      snap_state.saved_vm_running = runstate_is_running();
++    snap_state.in_progress = 1;
 +
-+      vm_stop(RUN_STATE_SAVE_VM);
++    snap_state.saved_vm_running = runstate_is_running();
 +
-+      if (!has_statefile)
-+              return;
++    vm_stop(RUN_STATE_SAVE_VM);
 +
-+      /* Open the image */
-+      bs = bdrv_new("vmstate");
-+      ret = bdrv_open(bs, statefile, bdrv_oflags, drv);
-+      if (ret < 0) {
-+              error_set(errp, QERR_OPEN_FILE_FAILED, statefile);
-+              goto restart;
-+      }
++    if (!has_statefile) {
++        return;
++    }
 +
-+      f = qemu_fopen_ops(bs, block_put_buffer, NULL, bdrv_fclose,
-+                         NULL, NULL, NULL);
-+      if (!f) {
-+              error_set(errp, QERR_OPEN_FILE_FAILED, statefile);
-+              goto restart;
-+      }
++    /* Open the image */
++    bs = bdrv_new("vmstate");
++    ret = bdrv_open(bs, statefile, bdrv_oflags, drv);
++    if (ret < 0) {
++        error_set(errp, QERR_OPEN_FILE_FAILED, statefile);
++        goto restart;
++    }
 +
-+      ret = qemu_savevm_state(f);
++    f = qemu_fopen_bdrv(bs, 1);
++    if (!f) {
++        error_set(errp, QERR_OPEN_FILE_FAILED, statefile);
++        goto restart;
++    }
 +
-+      bdrv_truncate(bs, qemu_ftell(f)); // ignore errors
++    ret = qemu_savevm_state(f);
 +
-+      qemu_fclose(f);
++    // try to truncate, but ignore errors (will fail on block devices).
++    bdrv_truncate(bs, qemu_ftell(f));
 +
-+      if (ret < 0) {
-+              error_set(errp, ERROR_CLASS_GENERIC_ERROR,
-+                        "Error %d while writing VM state\n", ret);
-+                      goto restart;
-+      }
-+end:
-+      if (bs)
-+              bdrv_delete(bs);
++    qemu_fclose(f);
 +
-+      return;
++    if (ret < 0) {
++        error_set(errp, ERROR_CLASS_GENERIC_ERROR,
++                  "Error %d while writing VM state\n", ret);
++        goto restart;
++    }
++out:
++    if (bs) {
++        bdrv_delete(bs);
++    }
++    return;
 +
 +restart:
 +
-+      snap_state.in_progress = 0;
++    snap_state.in_progress = 0;
 +
-+      if (snap_state.saved_vm_running) {
-+              vm_start();
-+      }
++    if (snap_state.saved_vm_running) {
++        vm_start();
++    }
 +
-+      goto end;
++    goto out;
 +}
 +
 +void qmp_snapshot_end(Error **errp)
 +{
-+      if (!snap_state.in_progress) {
-+              error_set(errp, ERROR_CLASS_GENERIC_ERROR,
-+                        "VM snapshot not started\n");
-+              return;
-+      }
-+      snap_state.in_progress = 0;
-+
-+      if (snap_state.saved_vm_running) {
-+              vm_start();
-+      }
-+}
++    if (!snap_state.in_progress) {
++        error_set(errp, ERROR_CLASS_GENERIC_ERROR,
++                  "VM snapshot not started\n");
++        return;
++    }
++    snap_state.in_progress = 0;
 +
-+/* Fixme: Copied from savevm */
-+static int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
-+                              const char *name)
-+{
-+    QEMUSnapshotInfo *sn_tab, *sn;
-+    int nb_sns, i, ret;
-+
-+    ret = -ENOENT;
-+    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
-+    if (nb_sns < 0)
-+        return ret;
-+    for(i = 0; i < nb_sns; i++) {
-+        sn = &sn_tab[i];
-+        if (!strcmp(sn->id_str, name) || !strcmp(sn->name, name)) {
-+            *sn_info = *sn;
-+            ret = 0;
-+            break;
-+        }
++    if (snap_state.saved_vm_running) {
++        vm_start();
 +    }
-+    g_free(sn_tab);
-+    return ret;
 +}
 +
 +void qmp_snapshot_drive(const char *device, const char *name, Error **errp)
 +{
-+      BlockDriverState *bs;
-+      QEMUSnapshotInfo sn1, *sn = &sn1;
-+      int ret;
++    BlockDriverState *bs;
++    QEMUSnapshotInfo sn1, *sn = &sn1;
++    int ret;
 +#ifdef _WIN32
-+      struct _timeb tb;
++    struct _timeb tb;
 +#else
-+      struct timeval tv;
++    struct timeval tv;
 +#endif
 +
-+      if (!snap_state.in_progress) {
-+              error_set(errp, ERROR_CLASS_GENERIC_ERROR,
-+                        "VM snapshot not started\n");
-+              return;
-+      }
-+
-+      bs = bdrv_find(device);
-+        if (!bs) {
-+              error_set(errp, QERR_DEVICE_NOT_FOUND, device);
-+              return;
-+      }
-+
-+        if (!bdrv_is_inserted(bs)) {
-+              error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
-+              return;
-+      }
-+
-+      if (bdrv_is_read_only(bs)) {
-+              error_set(errp, QERR_DEVICE_IS_READ_ONLY, device);
-+              return;
-+      }
-+
-+      if (!bdrv_can_snapshot(bs)) {
-+              error_set(errp, QERR_NOT_SUPPORTED);
-+              return;
-+      }
-+
-+      if (bdrv_snapshot_find(bs, sn, name) >= 0) {
-+              error_set(errp, ERROR_CLASS_GENERIC_ERROR,
-+                        "snapshot '%s' already exists", name);
-+              return;
-+      }
-+
-+      sn = &sn1;
-+      memset(sn, 0, sizeof(*sn));
++    if (!snap_state.in_progress) {
++        error_set(errp, ERROR_CLASS_GENERIC_ERROR,
++                  "VM snapshot not started\n");
++        return;
++    }
++
++    bs = bdrv_find(device);
++    if (!bs) {
++        error_set(errp, QERR_DEVICE_NOT_FOUND, device);
++        return;
++    }
++
++    if (!bdrv_is_inserted(bs)) {
++        error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
++        return;
++    }
++
++    if (bdrv_is_read_only(bs)) {
++        error_set(errp, QERR_DEVICE_IS_READ_ONLY, device);
++        return;
++    }
++
++    if (!bdrv_can_snapshot(bs)) {
++        error_set(errp, QERR_NOT_SUPPORTED);
++        return;
++    }
++
++    if (bdrv_snapshot_find(bs, sn, name) >= 0) {
++        error_set(errp, ERROR_CLASS_GENERIC_ERROR,
++                  "snapshot '%s' already exists", name);
++        return;
++    }
++
++    sn = &sn1;
++    memset(sn, 0, sizeof(*sn));
 +
 +#ifdef _WIN32
-+      _ftime(&tb);
-+      sn->date_sec = tb.time;
-+      sn->date_nsec = tb.millitm * 1000000;
++    _ftime(&tb);
++    sn->date_sec = tb.time;
++    sn->date_nsec = tb.millitm * 1000000;
 +#else
-+      gettimeofday(&tv, NULL);
-+      sn->date_sec = tv.tv_sec;
-+      sn->date_nsec = tv.tv_usec * 1000;
++    gettimeofday(&tv, NULL);
++    sn->date_sec = tv.tv_sec;
++    sn->date_nsec = tv.tv_usec * 1000;
 +#endif
-+      sn->vm_clock_nsec = qemu_get_clock_ns(vm_clock);
++    sn->vm_clock_nsec = qemu_get_clock_ns(vm_clock);
 +
-+      pstrcpy(sn->name, sizeof(sn->name), name);
++    pstrcpy(sn->name, sizeof(sn->name), name);
 +
-+      sn->vm_state_size = 0; /* do not save state */
++    sn->vm_state_size = 0; /* do not save state */
 +
-+      ret = bdrv_snapshot_create(bs, sn);
-+      if (ret < 0) {
-+                error_set(errp, ERROR_CLASS_GENERIC_ERROR, "Error while creating snapshot on '%s'\n", device);
-+              return;
-+      }
++    ret = bdrv_snapshot_create(bs, sn);
++    if (ret < 0) {
++        error_set(errp, ERROR_CLASS_GENERIC_ERROR,
++                  "Error while creating snapshot on '%s'\n", device);
++        return;
++    }
 +}
 +
-+void qmp_delete_drive_snapshot(const char *device, const char *name, Error **errp)
++void qmp_delete_drive_snapshot(const char *device, const char *name,
++                               Error **errp)
 +{
-+      BlockDriverState *bs;
-+      QEMUSnapshotInfo sn1, *sn = &sn1;
-+      int ret;
-+
-+      bs = bdrv_find(device);
-+        if (!bs) {
-+              error_set(errp, QERR_DEVICE_NOT_FOUND, device);
-+              return;
-+      }
-+      if (bdrv_is_read_only(bs)) {
-+              error_set(errp, QERR_DEVICE_IS_READ_ONLY, device);
-+              return;
-+      }
-+
-+      if (!bdrv_can_snapshot(bs)) {
-+              error_set(errp, QERR_NOT_SUPPORTED);
-+              return;
-+      }
-+
-+      if (bdrv_snapshot_find(bs, sn, name) < 0) {
-+              /* return success if snapshot does not exists */
-+              return;
-+      }
-+
-+      ret = bdrv_snapshot_delete(bs, name);
-+      if (ret < 0) {
-+                error_set(errp, ERROR_CLASS_GENERIC_ERROR, "Error while deleting snapshot on '%s'\n", device);
-+              return;
-+      }
++    BlockDriverState *bs;
++    QEMUSnapshotInfo sn1, *sn = &sn1;
++    int ret;
++
++    bs = bdrv_find(device);
++    if (!bs) {
++        error_set(errp, QERR_DEVICE_NOT_FOUND, device);
++        return;
++    }
++    if (bdrv_is_read_only(bs)) {
++        error_set(errp, QERR_DEVICE_IS_READ_ONLY, device);
++        return;
++    }
++
++    if (!bdrv_can_snapshot(bs)) {
++        error_set(errp, QERR_NOT_SUPPORTED);
++        return;
++    }
++
++    if (bdrv_snapshot_find(bs, sn, name) < 0) {
++        /* return success if snapshot does not exists */
++        return;
++    }
++
++    ret = bdrv_snapshot_delete(bs, name);
++    if (ret < 0) {
++        error_set(errp, ERROR_CLASS_GENERIC_ERROR,
++                  "Error while deleting snapshot on '%s'\n", device);
++        return;
++    }
 +}
 Index: new/qmp-commands.hx
 ===================================================================
---- new.orig/qmp-commands.hx   2012-09-07 07:41:45.000000000 +0200
-+++ new/qmp-commands.hx        2012-09-13 09:30:33.000000000 +0200
+--- new.orig/qmp-commands.hx   2012-09-18 06:20:41.000000000 +0200
++++ new/qmp-commands.hx        2012-09-18 08:43:25.000000000 +0200
 @@ -2514,3 +2514,27 @@
          .args_type  = "",
          .mhandler.cmd_new = qmp_marshal_input_query_target,
@@ -278,8 +247,8 @@ Index: new/qmp-commands.hx
 +    },
 Index: new/hmp.c
 ===================================================================
---- new.orig/hmp.c     2012-09-07 07:41:45.000000000 +0200
-+++ new/hmp.c  2012-09-13 09:22:06.000000000 +0200
+--- new.orig/hmp.c     2012-09-18 06:20:41.000000000 +0200
++++ new/hmp.c  2012-09-18 08:43:25.000000000 +0200
 @@ -1102,3 +1102,40 @@
      qmp_closefd(fdname, &errp);
      hmp_handle_error(mon, &errp);
@@ -323,8 +292,8 @@ Index: new/hmp.c
 +}
 Index: new/hmp.h
 ===================================================================
---- new.orig/hmp.h     2012-09-07 07:41:45.000000000 +0200
-+++ new/hmp.h  2012-09-13 09:22:06.000000000 +0200
+--- new.orig/hmp.h     2012-09-18 06:20:41.000000000 +0200
++++ new/hmp.h  2012-09-18 08:43:25.000000000 +0200
 @@ -71,5 +71,9 @@
  void hmp_netdev_del(Monitor *mon, const QDict *qdict);
  void hmp_getfd(Monitor *mon, const QDict *qdict);
@@ -337,8 +306,8 @@ Index: new/hmp.h
  #endif
 Index: new/hmp-commands.hx
 ===================================================================
---- new.orig/hmp-commands.hx   2012-09-07 07:41:45.000000000 +0200
-+++ new/hmp-commands.hx        2012-09-13 09:22:06.000000000 +0200
+--- new.orig/hmp-commands.hx   2012-09-18 06:20:41.000000000 +0200
++++ new/hmp-commands.hx        2012-09-18 08:43:25.000000000 +0200
 @@ -1494,3 +1494,35 @@
  STEXI
  @end table
@@ -375,33 +344,11 @@ Index: new/hmp-commands.hx
 +        .help       = "Resume VM after snaphot.",
 +        .mhandler.cmd = hmp_snapshot_end,
 +    },
-Index: new/savevm.c
-===================================================================
---- new.orig/savevm.c  2012-09-07 07:41:45.000000000 +0200
-+++ new/savevm.c       2012-09-14 11:32:17.000000000 +0200
-@@ -404,7 +404,7 @@
-     return bdrv_flush(opaque);
- }
--static QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int is_writable)
-+QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int is_writable)
- {
-     if (is_writable)
-         return qemu_fopen_ops(bs, block_put_buffer, NULL, bdrv_fclose, 
-@@ -1724,7 +1724,7 @@
-     }
- }
--static int qemu_savevm_state(QEMUFile *f)
-+int qemu_savevm_state(QEMUFile *f)
- {
-     int ret;
-     MigrationParams params = {
 Index: new/sysemu.h
 ===================================================================
---- new.orig/sysemu.h  2012-09-07 07:41:46.000000000 +0200
-+++ new/sysemu.h       2012-09-13 09:22:06.000000000 +0200
-@@ -83,6 +83,7 @@
+--- new.orig/sysemu.h  2012-09-18 07:35:53.000000000 +0200
++++ new/sysemu.h       2012-09-18 08:43:25.000000000 +0200
+@@ -84,6 +84,7 @@
  int qemu_savevm_state_iterate(QEMUFile *f);
  int qemu_savevm_state_complete(QEMUFile *f);
  void qemu_savevm_state_cancel(QEMUFile *f);
@@ -409,15 +356,16 @@ Index: new/sysemu.h
  int qemu_loadvm_state(QEMUFile *f);
  
  /* SLIRP */
-Index: new/qemu-file.h
+Index: new/savevm.c
 ===================================================================
---- new.orig/qemu-file.h       2012-09-14 11:51:31.000000000 +0200
-+++ new/qemu-file.h    2012-09-14 11:51:47.000000000 +0200
-@@ -68,6 +68,7 @@
- QEMUFile *qemu_fopen(const char *filename, const char *mode);
- QEMUFile *qemu_fdopen(int fd, const char *mode);
- QEMUFile *qemu_fopen_socket(int fd);
-+QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int is_writable);
- QEMUFile *qemu_popen(FILE *popen_file, const char *mode);
- QEMUFile *qemu_popen_cmd(const char *command, const char *mode);
- int qemu_stdio_fd(QEMUFile *f);
+--- new.orig/savevm.c  2012-09-18 08:53:28.000000000 +0200
++++ new/savevm.c       2012-09-18 08:53:55.000000000 +0200
+@@ -1743,7 +1743,7 @@
+     }
+ }
+-static int qemu_savevm_state(QEMUFile *f)
++int qemu_savevm_state(QEMUFile *f)
+ {
+     int ret;
+     MigrationParams params = {
diff --git a/debian/patches/load-state-from-blockdev.patch b/debian/patches/load-state-from-blockdev.patch
new file mode 100644 (file)
index 0000000..1c00c6c
--- /dev/null
@@ -0,0 +1,124 @@
+Index: new/savevm.c
+===================================================================
+--- new.orig/savevm.c  2012-09-18 07:20:45.000000000 +0200
++++ new/savevm.c       2012-09-18 07:36:55.000000000 +0200
+@@ -2223,6 +2223,50 @@
+     return;
+ }
++int load_state_from_blockdev(const char *filename)
++{
++    BlockDriverState *bs = NULL;
++    BlockDriver *drv = NULL;
++    QEMUFile *f;
++    int bdrv_oflags = BDRV_O_NOCACHE | BDRV_O_RDWR;
++    int ret = -1;
++
++    bs = bdrv_new("vmstate");
++    ret = bdrv_open(bs, filename, bdrv_oflags, drv);
++    if (ret < 0) {
++        error_report("Could not open VM state file");
++        goto the_end;
++    }
++
++    /* Flush all IO requests so they don't interfere with the new state.  */
++    bdrv_drain_all();
++
++    /* restore the VM state */
++    f = qemu_fopen_bdrv(bs, 0);
++    if (!f) {
++        error_report("Could not open VM state file");
++        ret = -EINVAL;
++        goto the_end;
++    }
++
++    qemu_system_reset(VMRESET_SILENT);
++    ret = qemu_loadvm_state(f);
++
++    qemu_fclose(f);
++    if (ret < 0) {
++        error_report("Error %d while loading VM state", ret);
++        goto the_end;
++    }
++
++    ret = 0;
++
++ the_end:
++    if (bs) {
++        bdrv_delete(bs);
++    }
++    return ret;
++}
++
+ int load_vmstate(const char *name)
+ {
+     BlockDriverState *bs, *bs_vm_state;
+Index: new/sysemu.h
+===================================================================
+--- new.orig/sysemu.h  2012-09-18 07:35:26.000000000 +0200
++++ new/sysemu.h       2012-09-18 07:35:53.000000000 +0200
+@@ -72,6 +72,7 @@
+ void do_savevm(Monitor *mon, const QDict *qdict);
+ int load_vmstate(const char *name);
++int load_state_from_blockdev(const char *filename);
+ void do_delvm(Monitor *mon, const QDict *qdict);
+ void do_info_snapshots(Monitor *mon);
+Index: new/qemu-options.hx
+===================================================================
+--- new.orig/qemu-options.hx   2012-09-18 07:39:54.000000000 +0200
++++ new/qemu-options.hx        2012-09-18 07:52:56.000000000 +0200
+@@ -2477,6 +2477,19 @@
+ Start right away with a saved state (@code{loadvm} in monitor)
+ ETEXI
++DEF("loadstate", HAS_ARG, QEMU_OPTION_loadstate, \
++    "-loadstate file\n" \
++    "                start right away with a saved state\n",
++    QEMU_ARCH_ALL)
++STEXI
++@item -loadstate @var{file}
++@findex -loadstate
++Start right away with a saved state. This option does not rollback
++disk state like @code{loadvm}, so user must make sure that disk
++have correct state. @var{file} can be any valid device URL. See the section
++for "Device URL Syntax" for more information.
++ETEXI
++
+ #ifndef _WIN32
+ DEF("daemonize", 0, QEMU_OPTION_daemonize, \
+     "-daemonize      daemonize QEMU after initializing\n", QEMU_ARCH_ALL)
+Index: new/vl.c
+===================================================================
+--- new.orig/vl.c      2012-09-18 07:53:19.000000000 +0200
++++ new/vl.c   2012-09-18 07:55:47.000000000 +0200
+@@ -2364,6 +2364,7 @@
+     int optind;
+     const char *optarg;
+     const char *loadvm = NULL;
++    const char *loadstate = NULL;
+     QEMUMachine *machine;
+     const char *cpu_model;
+     const char *vga_model = "none";
+@@ -2998,6 +2999,9 @@
+           case QEMU_OPTION_loadvm:
+               loadvm = optarg;
+               break;
++          case QEMU_OPTION_loadstate:
++              loadstate = optarg;
++              break;
+             case QEMU_OPTION_full_screen:
+                 full_screen = 1;
+                 break;
+@@ -3821,6 +3825,10 @@
+         if (load_vmstate(loadvm) < 0) {
+             autostart = 0;
+         }
++    } else if (loadstate) {
++        if (load_state_from_blockdev(loadstate) < 0) {
++            autostart = 0;
++        }
+     }
+     if (incoming) {
diff --git a/debian/patches/move-bdrv-snapshot-find.patch b/debian/patches/move-bdrv-snapshot-find.patch
new file mode 100644 (file)
index 0000000..3f411e8
--- /dev/null
@@ -0,0 +1,79 @@
+Index: new/block.c
+===================================================================
+--- new.orig/block.c   2012-09-18 08:38:03.000000000 +0200
++++ new/block.c        2012-09-18 08:39:00.000000000 +0200
+@@ -2724,6 +2724,28 @@
+     return -ENOTSUP;
+ }
++int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
++                     const char *name)
++{
++    QEMUSnapshotInfo *sn_tab, *sn;
++    int nb_sns, i, ret;
++
++    ret = -ENOENT;
++    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
++    if (nb_sns < 0)
++        return ret;
++    for(i = 0; i < nb_sns; i++) {
++        sn = &sn_tab[i];
++        if (!strcmp(sn->id_str, name) || !strcmp(sn->name, name)) {
++            *sn_info = *sn;
++            ret = 0;
++            break;
++        }
++    }
++    g_free(sn_tab);
++    return ret;
++}
++
+ int bdrv_snapshot_load_tmp(BlockDriverState *bs,
+         const char *snapshot_name)
+ {
+Index: new/block.h
+===================================================================
+--- new.orig/block.h   2012-09-18 08:38:03.000000000 +0200
++++ new/block.h        2012-09-18 08:39:42.000000000 +0200
+@@ -302,6 +302,8 @@
+ int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id);
+ int bdrv_snapshot_list(BlockDriverState *bs,
+                        QEMUSnapshotInfo **psn_info);
++int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
++                     const char *name);
+ int bdrv_snapshot_load_tmp(BlockDriverState *bs,
+                            const char *snapshot_name);
+ char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn);
+Index: new/savevm.c
+===================================================================
+--- new.orig/savevm.c  2012-09-18 08:38:03.000000000 +0200
++++ new/savevm.c       2012-09-18 08:39:05.000000000 +0200
+@@ -2034,28 +2034,6 @@
+     return ret;
+ }
+-static int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
+-                              const char *name)
+-{
+-    QEMUSnapshotInfo *sn_tab, *sn;
+-    int nb_sns, i, ret;
+-
+-    ret = -ENOENT;
+-    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
+-    if (nb_sns < 0)
+-        return ret;
+-    for(i = 0; i < nb_sns; i++) {
+-        sn = &sn_tab[i];
+-        if (!strcmp(sn->id_str, name) || !strcmp(sn->name, name)) {
+-            *sn_info = *sn;
+-            ret = 0;
+-            break;
+-        }
+-    }
+-    g_free(sn_tab);
+-    return ret;
+-}
+-
+ /*
+  * Deletes snapshots of a given name in all opened images.
+  */
index e1f6444dadb657bc646f462d4323d30dac39613f..2581fd15289430b88c2d23f2ee2dfd1b0b2e3dbd 100644 (file)
@@ -8,7 +8,8 @@ update-cpus-x86_64.conf-to-rhel6.2-version.patch
 vencrypt-auth-plain.patch
 ahci-add_migration-support.patch
 ahci-properly-reset-pxcmd.patch
-#modify-qapi-schema.patch
-#implement-snapshot-drive.patch
-internal-snapshot.patch
 fix-qemu-img-snapshot-removal.patch
+implement-qemu-fopen-bdrv.patch
+load-state-from-blockdev.patch
+move-bdrv-snapshot-find.patch
+internal-snapshot.patch