This commit is contained in:
committed by
Git OBS Bridge
parent
8ae8ea2a74
commit
f5d6338f4d
238
snapshot-ioemu-save.patch
Normal file
238
snapshot-ioemu-save.patch
Normal file
@@ -0,0 +1,238 @@
|
||||
Index: xen-3.3.0-testing/tools/ioemu/vl.c
|
||||
===================================================================
|
||||
--- xen-3.3.0-testing.orig/tools/ioemu/vl.c
|
||||
+++ xen-3.3.0-testing/tools/ioemu/vl.c
|
||||
@@ -108,6 +108,8 @@
|
||||
|
||||
#include "exec-all.h"
|
||||
|
||||
+#include "block_int.h"
|
||||
+
|
||||
#define DEFAULT_NETWORK_SCRIPT "/etc/xen/qemu-ifup"
|
||||
#ifdef _BSD
|
||||
#define DEFAULT_BRIDGE "bridge0"
|
||||
@@ -5155,6 +5157,83 @@ void do_loadvm(const char *name)
|
||||
if (saved_vm_running)
|
||||
vm_start();
|
||||
}
|
||||
+
|
||||
+int save_disk_snapshots(const char* name)
|
||||
+{
|
||||
+ BlockDriverState *bs;
|
||||
+ QEMUSnapshotInfo sn, old_sn;
|
||||
+ struct timeval tv;
|
||||
+ int saved_vm_running;
|
||||
+ int can_snapshot;
|
||||
+ int i;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ saved_vm_running = vm_running;
|
||||
+ vm_stop(0);
|
||||
+
|
||||
+ qemu_aio_flush();
|
||||
+
|
||||
+ /* Ensure that all images support snapshots or are read-only */
|
||||
+ for(i = 0; i < MAX_DISKS; i++) {
|
||||
+ bs = bs_table[i];
|
||||
+
|
||||
+ if (!bs || !bs->drv)
|
||||
+ continue;
|
||||
+
|
||||
+ can_snapshot = bs->drv->bdrv_snapshot_create && bdrv_can_snapshot(bs);
|
||||
+ if (!bdrv_is_read_only(bs) && !can_snapshot) {
|
||||
+ fprintf(stderr, "Error: bdrv %s (%s) doesn't support snapshots\n",
|
||||
+ bdrv_get_device_name(bs), bs->drv->format_name);
|
||||
+ ret = -ENOTSUP;
|
||||
+ goto the_end;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* fill auxiliary fields */
|
||||
+ memset(&sn, 0, sizeof(sn));
|
||||
+ gettimeofday(&tv, NULL);
|
||||
+ sn.date_sec = tv.tv_sec;
|
||||
+ sn.date_nsec = tv.tv_usec * 1000;
|
||||
+ sn.vm_clock_nsec = qemu_get_clock(vm_clock);
|
||||
+ pstrcpy(sn.name, sizeof(sn.name), name);
|
||||
+
|
||||
+ for(i = 0; i < MAX_DISKS; i++) {
|
||||
+ bs = bs_table[i];
|
||||
+
|
||||
+ /* No snapshots on read-only images */
|
||||
+ if (!bs || !bs->drv || bdrv_is_read_only(bs))
|
||||
+ continue;
|
||||
+
|
||||
+ /* Delete old snapshot of the same name */
|
||||
+ if (bdrv_snapshot_find(bs, &old_sn, name) >= 0) {
|
||||
+ ret = bdrv_snapshot_delete(bs, old_sn.id_str);
|
||||
+ if (ret < 0) {
|
||||
+ fprintf(stderr, "Error while deleting snapshot on '%s'\n",
|
||||
+ bdrv_get_device_name(bs));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Create the snapshot */
|
||||
+ fprintf(stderr, "Creating snapshot on '%s' (%s)\n",
|
||||
+ bdrv_get_device_name(bs), bs->drv->format_name);
|
||||
+ ret = bdrv_snapshot_create(bs, &sn);
|
||||
+ if (ret < 0) {
|
||||
+ fprintf(stderr, "Error while creating snapshot on '%s': %d (%s)\n",
|
||||
+ bdrv_get_device_name(bs), ret, strerror(-ret));
|
||||
+ goto the_end;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ fprintf(stderr, "Created all snapshots\n");
|
||||
+
|
||||
+the_end:
|
||||
+ if (saved_vm_running)
|
||||
+ vm_start();
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+
|
||||
#else
|
||||
void do_savevm(const char *name)
|
||||
{
|
||||
Index: xen-3.3.0-testing/tools/ioemu/target-i386-dm/helper2.c
|
||||
===================================================================
|
||||
--- xen-3.3.0-testing.orig/tools/ioemu/target-i386-dm/helper2.c
|
||||
+++ xen-3.3.0-testing/tools/ioemu/target-i386-dm/helper2.c
|
||||
@@ -92,6 +92,9 @@ int send_vcpu = 0;
|
||||
#define NR_CPUS 32
|
||||
evtchn_port_t ioreq_local_port[NR_CPUS];
|
||||
|
||||
+/** Name of the snapshot which should be saved */
|
||||
+char* snapshot_name;
|
||||
+
|
||||
CPUX86State *cpu_x86_init(void)
|
||||
{
|
||||
CPUX86State *env;
|
||||
@@ -556,9 +559,24 @@ int main_loop(void)
|
||||
main_loop_wait(1); /* For the select() on events */
|
||||
|
||||
/* Save the device state */
|
||||
- asprintf(&qemu_file, "/var/lib/xen/qemu-save.%d", domid);
|
||||
- do_savevm(qemu_file);
|
||||
- free(qemu_file);
|
||||
+ switch (suspend_requested) {
|
||||
+ case SUSPEND_SAVEVM:
|
||||
+ asprintf(&qemu_file, "/var/lib/xen/qemu-save.%d", domid);
|
||||
+ do_savevm(qemu_file);
|
||||
+ free(qemu_file);
|
||||
+ break;
|
||||
+
|
||||
+ case SUSPEND_SNAPSHOT:
|
||||
+ // TODO Error reporting
|
||||
+ if (snapshot_name != NULL) {
|
||||
+ save_disk_snapshots(snapshot_name);
|
||||
+ free(snapshot_name);
|
||||
+ snapshot_name = NULL;
|
||||
+ } else {
|
||||
+ fprintf(logfile, "No snapshot name given\n");
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
xenstore_record_dm_state("paused");
|
||||
|
||||
Index: xen-3.3.0-testing/tools/ioemu/vl.h
|
||||
===================================================================
|
||||
--- xen-3.3.0-testing.orig/tools/ioemu/vl.h
|
||||
+++ xen-3.3.0-testing/tools/ioemu/vl.h
|
||||
@@ -59,7 +59,6 @@
|
||||
extern int qemu_ftruncate64(int, int64_t);
|
||||
#define ftruncate qemu_ftruncate64
|
||||
|
||||
-
|
||||
static inline char *realpath(const char *path, char *resolved_path)
|
||||
{
|
||||
_fullpath(resolved_path, path, _MAX_PATH);
|
||||
@@ -72,6 +71,11 @@ static inline char *realpath(const char
|
||||
#define PRIo64 "I64o"
|
||||
#endif
|
||||
|
||||
+enum {
|
||||
+ SUSPEND_SAVEVM = 1,
|
||||
+ SUSPEND_SNAPSHOT = 2
|
||||
+};
|
||||
+
|
||||
#ifdef QEMU_TOOL
|
||||
|
||||
/* we use QEMU_TOOL in the command line tools which do not depend on
|
||||
@@ -557,6 +561,8 @@ void do_loadvm(const char *name);
|
||||
void do_delvm(const char *name);
|
||||
void do_info_snapshots(void);
|
||||
|
||||
+int save_disk_snapshots(const char* name);
|
||||
+
|
||||
/* bottom halves */
|
||||
typedef void QEMUBHFunc(void *opaque);
|
||||
|
||||
Index: xen-3.3.0-testing/tools/ioemu/xenstore.c
|
||||
===================================================================
|
||||
--- xen-3.3.0-testing.orig/tools/ioemu/xenstore.c
|
||||
+++ xen-3.3.0-testing/tools/ioemu/xenstore.c
|
||||
@@ -536,6 +536,7 @@ static void xenstore_process_dm_command_
|
||||
char *path = NULL, *command = NULL, *par = NULL;
|
||||
unsigned int len;
|
||||
extern int suspend_requested;
|
||||
+ extern char* snapshot_name;
|
||||
|
||||
if (pasprintf(&path,
|
||||
"/local/domain/0/device-model/%u/command", domid) == -1) {
|
||||
@@ -548,7 +549,18 @@ static void xenstore_process_dm_command_
|
||||
|
||||
if (!strncmp(command, "save", len)) {
|
||||
fprintf(logfile, "dm-command: pause and save state\n");
|
||||
- suspend_requested = 1;
|
||||
+ suspend_requested = SUSPEND_SAVEVM;
|
||||
+ } else if (!strncmp(command, "snapshot", len)) {
|
||||
+ fprintf(logfile, "dm-command: pause and snapshot disks\n");
|
||||
+ suspend_requested = SUSPEND_SNAPSHOT;
|
||||
+
|
||||
+ if (pasprintf(&path,
|
||||
+ "/local/domain/0/device-model/%u/parameter", domid) == -1) {
|
||||
+ fprintf(logfile, "out of memory reading dm command parameter\n");
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ snapshot_name = xs_read(xsh, XBT_NULL, path, &len);
|
||||
} else if (!strncmp(command, "continue", len)) {
|
||||
fprintf(logfile, "dm-command: continue after state save\n");
|
||||
suspend_requested = 0;
|
||||
Index: xen-3.3.0-testing/tools/ioemu/hw/xen_blktap.c
|
||||
===================================================================
|
||||
--- xen-3.3.0-testing.orig/tools/ioemu/hw/xen_blktap.c
|
||||
+++ xen-3.3.0-testing/tools/ioemu/hw/xen_blktap.c
|
||||
@@ -221,8 +221,12 @@ static int open_disk(struct td_state *s,
|
||||
struct disk_id id;
|
||||
BlockDriverState* bs;
|
||||
|
||||
+#ifndef QEMU_TOOL
|
||||
+ int i;
|
||||
+#endif
|
||||
+
|
||||
DPRINTF("Opening %s\n", path);
|
||||
- bs = calloc(1, sizeof(*bs));
|
||||
+ bs = bdrv_new("blktap");
|
||||
|
||||
memset(&id, 0, sizeof(struct disk_id));
|
||||
|
||||
@@ -238,6 +242,15 @@ static int open_disk(struct td_state *s,
|
||||
|
||||
s->info = ((s->flags & TD_RDONLY) ? VDISK_READONLY : 0);
|
||||
|
||||
+#ifndef QEMU_TOOL
|
||||
+ for (i = 0; i < MAX_DISKS + MAX_SCSI_DISKS; i++) {
|
||||
+ if (bs_table[i] == NULL) {
|
||||
+ bs_table[i] = bs;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user