Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:12.2
xen
snapshot-ioemu-save.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File snapshot-ioemu-save.patch of Package xen
Index: xen-4.1.2-testing/tools/ioemu-qemu-xen/savevm.c =================================================================== --- xen-4.1.2-testing.orig/tools/ioemu-qemu-xen/savevm.c +++ xen-4.1.2-testing/tools/ioemu-qemu-xen/savevm.c @@ -28,6 +28,7 @@ #include "sysemu.h" #include "qemu-timer.h" #include "qemu-char.h" +#include "block_int.h" #include "block.h" #include "audio/audio.h" #include "migration.h" @@ -1025,6 +1026,86 @@ static int bdrv_snapshot_find(BlockDrive return ret; } +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; + + /* Deal with all aio submit */ + qemu_aio_flush(); + /* Do fsync at backend fs */ + ret = bdrv_flush_all(); + if (ret) + fprintf(stderr, "Fsync error[%d] when do snapshot[%s]\n", ret, name); + + saved_vm_running = vm_running; + vm_stop(0); + + /* Ensure that all images support snapshots or are read-only */ + for(i = 0; i < MAX_DRIVES; i++) { + bs = drives_table[i].bdrv; + + 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_DRIVES; i++) { + bs = drives_table[i].bdrv; + + /* 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; +} + #ifndef CONFIG_DM void do_savevm(const char *name) Index: xen-4.1.2-testing/tools/ioemu-qemu-xen/i386-dm/helper2.c =================================================================== --- xen-4.1.2-testing.orig/tools/ioemu-qemu-xen/i386-dm/helper2.c +++ xen-4.1.2-testing/tools/ioemu-qemu-xen/i386-dm/helper2.c @@ -112,6 +112,9 @@ int send_vcpu = 0; //the evtchn port for polling the notification, evtchn_port_t *ioreq_local_port; +/** Name of the snapshot which should be saved */ +char* snapshot_name; + CPUX86State *cpu_x86_init(const char *cpu_model) { CPUX86State *env; @@ -556,6 +559,7 @@ int main_loop(void) int evtchn_fd = xce_handle == NULL ? -1 : xc_evtchn_fd(xce_handle); char *qemu_file; fd_set fds; + int ret; main_loop_prepare(); @@ -588,11 +592,43 @@ 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 (xen_pause_requested) { + case SUSPEND_SAVEVM: + asprintf(&qemu_file, "/var/lib/xen/qemu-save.%d", domid); + do_savevm(qemu_file); + free(qemu_file); + xenstore_record_dm_state("paused"); + break; + + case SUSPEND_SNAPSHOT: + if (snapshot_name != NULL) { + ret = save_disk_snapshots(snapshot_name); + free(snapshot_name); + snapshot_name = NULL; + + switch (ret) { + case 0: + xenstore_record_dm_state("paused"); + break; + case -ENOTSUP: + xenstore_record_dm_error("Snapshots not supported on all" + " attached read-write disks"); + break; + case -ENOENT: + xenstore_record_dm_error("A snapshot with the same name" + " already exists"); + break; + default: + xenstore_record_dm_error("An error occurred while saving" + " the snapshot"); + break; + } + } else { + xenstore_record_dm_error("No snapshot name given"); + } + break; + } - xenstore_record_dm_state("paused"); /* Wait to be allowed to continue */ while (xen_pause_requested) { Index: xen-4.1.2-testing/tools/ioemu-qemu-xen/qemu-xen.h =================================================================== --- xen-4.1.2-testing.orig/tools/ioemu-qemu-xen/qemu-xen.h +++ xen-4.1.2-testing/tools/ioemu-qemu-xen/qemu-xen.h @@ -34,6 +34,15 @@ void qemu_invalidate_map_cache(void) #define mapcache_lock() ((void)0) #define mapcache_unlock() ((void)0) +/* Reason for xen_pause_requested */ +enum { + SUSPEND_SAVEVM = 1, + SUSPEND_SNAPSHOT = 2 +}; + +/* xen-vl-extra.c */ +int save_disk_snapshots(const char* name); + /* helper2.c */ extern long time_offset; void timeoffset_get(void); @@ -70,6 +79,7 @@ int xenstore_fd(void); void xenstore_process_event(void *opaque); void xenstore_record_dm(const char *subpath, const char *state); void xenstore_record_dm_state(const char *state); +void xenstore_record_dm_error(const char *errmsg); void xenstore_check_new_media_present(int timeout); void xenstore_read_vncpasswd(int domid, char *pwbuf, size_t pwbuflen); void xenstore_write_vslots(char *vslots); Index: xen-4.1.2-testing/tools/ioemu-qemu-xen/xenstore.c =================================================================== --- xen-4.1.2-testing.orig/tools/ioemu-qemu-xen/xenstore.c +++ xen-4.1.2-testing/tools/ioemu-qemu-xen/xenstore.c @@ -17,6 +17,7 @@ #include "exec-all.h" #include "sysemu.h" +#include "qemu-xen.h" #include "console.h" #include "hw.h" @@ -905,6 +906,7 @@ static void xenstore_process_dm_command_ { char *path = NULL, *command = NULL, *par = NULL; unsigned int len; + extern char* snapshot_name; if (pasprintf(&path, "/local/domain/0/device-model/%u/command", domid) == -1) { @@ -920,7 +922,18 @@ static void xenstore_process_dm_command_ if (!strncmp(command, "save", len)) { fprintf(logfile, "dm-command: pause and save state\n"); - xen_pause_requested = 1; + xen_pause_requested = SUSPEND_SAVEVM; + } else if (!strncmp(command, "snapshot", len)) { + fprintf(logfile, "dm-command: pause and snapshot disks\n"); + xen_pause_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"); xen_pause_requested = 0; @@ -1083,6 +1096,13 @@ static void xenstore_process_vcpu_set_ev return; } +void xenstore_record_dm_error(const char *errmsg) +{ + fprintf(logfile, "%s\n", errmsg); + xenstore_record_dm("error", errmsg); + xenstore_record_dm_state("error"); +} + static void xenstore_process_media_change_event(char **vec) { char *media_present = NULL;
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor