[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v2 11/12] qapi: Convert savevm
From: |
Kevin Wolf |
Subject: |
Re: [Qemu-devel] [PATCH v2 11/12] qapi: Convert savevm |
Date: |
Fri, 3 May 2013 14:52:59 +0200 |
User-agent: |
Mutt/1.5.21 (2010-09-15) |
Am 24.04.2013 um 17:32 hat Pavel Hrdina geschrieben:
> QMP command vm-snapshot-save takes one parameter name and the name is
> mandatory. The command returns SnapshotInfo on success, otherwise it returns
> an error message. If there is a snapshot with the same name it also returns
> an error message and if you want to overwrite that snapshot, you will have to
> at first call vm-snapshot-delete.
>
> HMP command savevm now has one optional parameter name and one flag -f.
> If the name parameter isn't provided the HMP command will create new one for
> internally used vm-snapshot-save. You can also specify the -f flag for
> overwrite
> existing snapshot which will internally use vm-snapshot-delete before
> vm-snapshot-save, otherwise it will print an error message if there is already
> a snapshot with the same name. If something else goes wrong, an error message
> will be printed.
>
> These improves behavior of the command to let you select only the name of the
> snapshot you want to create. This will ensure that if you want snapshot with
> the name '2', it will not rewrite or fail if there is any snapshot with id
> '2'.
>
> Signed-off-by: Pavel Hrdina <address@hidden>
> --- a/hmp.c
> +++ b/hmp.c
> @@ -1491,3 +1491,52 @@ void hmp_vm_snapshot_load(Monitor *mon, const QDict
> *qdict)
> qapi_free_SnapshotInfo(info);
> hmp_handle_error(mon, &local_err);
> }
> +
> +void hmp_vm_snapshot_save(Monitor *mon, const QDict *qdict)
> +{
> + const char *name = qdict_get_try_str(qdict, "name");
> + bool force = qdict_get_try_bool(qdict, "force", 0);
> + Error *local_err = NULL;
> + SnapshotInfo *info = NULL;
> + qemu_timeval tv;
> + struct tm tm;
> + char tmp_name[256];
> +
> + if (!name) {
> + localtime_r((const time_t *)&tv.tv_sec, &tm);
> + strftime(tmp_name, sizeof(tmp_name), "vm-%Y%m%d%H%M%S", &tm);
> + name = tmp_name;
> + }
> +
> + if (force) {
> + info = qmp_vm_snapshot_delete(true, name, false, NULL, &local_err);
> + /* We don't need print info about deleted snapshot. It still needs to
> + * be freed. */
> + qapi_free_SnapshotInfo(info);
> + if (error_is_set(&local_err)) {
> + hmp_handle_error(mon, &local_err);
> + return;
> + }
> + }
Deleting a snapshot that doesn't exist returns an error. This means that
you can use -f _only_ to overwrite a snapshot. I think this is
unexpected, with -f all cases that work without -f should keep working.
> +
> + info = qmp_vm_snapshot_save(name, &local_err);
> +
> + if (info) {
> + char buf[256];
> + QEMUSnapshotInfo sn = {
> + .vm_state_size = info->vm_state_size,
> + .date_sec = info->date_sec,
> + .date_nsec = info->date_nsec,
> + .vm_clock_nsec = info->vm_clock_sec * 1000000000 +
> + info->vm_clock_nsec,
> + };
> + pstrcpy(sn.id_str, sizeof(sn.id_str), info->id);
> + pstrcpy(sn.name, sizeof(sn.name), info->name);
> + monitor_printf(mon, "Created snapshot's info:\n");
> + monitor_printf(mon, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf),
> NULL));
> + monitor_printf(mon, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf),
> &sn));
> + }
> +
> + qapi_free_SnapshotInfo(info);
> + hmp_handle_error(mon, &local_err);
> +}
> --- a/savevm.c
> +++ b/savevm.c
> @@ -2398,36 +2369,24 @@ void do_savevm(Monitor *mon, const QDict *qdict)
> sn->date_nsec = tv.tv_usec * 1000;
> sn->vm_clock_nsec = qemu_get_clock_ns(vm_clock);
>
> - if (name) {
> - if (bdrv_snapshot_find(bs, old_sn, name, NULL, NULL, true)) {
> - pstrcpy(sn->name, sizeof(sn->name), old_sn->name);
> - pstrcpy(sn->id_str, sizeof(sn->id_str), old_sn->id_str);
> - } else {
> - pstrcpy(sn->name, sizeof(sn->name), name);
> - }
> - } else {
> - /* cast below needed for OpenBSD where tv_sec is still 'long' */
> - localtime_r((const time_t *)&tv.tv_sec, &tm);
> - strftime(sn->name, sizeof(sn->name), "vm-%Y%m%d%H%M%S", &tm);
> - }
> -
> - /* Delete old snapshots of the same name */
> - if (name && del_existing_snapshots(mon, name) < 0) {
> + if (bdrv_snapshot_find(bs, old_sn, name, NULL, NULL, false)) {
> + error_setg(errp, "Snapshot '%s' exists", name);
This is only checked for the VM state device. For all other devices the
case isn't handled any more.
> goto the_end;
> + } else {
> + pstrcpy(sn->name, sizeof(sn->name), name);
> }
>
> /* save the VM state */
> f = qemu_fopen_bdrv(bs, 1);
> if (!f) {
> - monitor_printf(mon, "Could not open VM state file\n");
> + error_setg(errp, "Failed to open '%s' file",
> bdrv_get_device_name(bs));
> goto the_end;
> }
> qemu_savevm_state(f, &local_err);
> vm_state_size = qemu_ftell(f);
> qemu_fclose(f);
> if (error_is_set(&local_err)) {
> - qerror_report_err(local_err);
> - error_free(local_err);
> + error_propagate(errp, local_err);
> goto the_end;
> }
>
> @@ -2440,18 +2399,29 @@ void do_savevm(Monitor *mon, const QDict *qdict)
> sn->vm_state_size = (bs == bs1 ? vm_state_size : 0);
> bdrv_snapshot_create(bs1, sn, &local_err);
> if (error_is_set(&local_err)) {
> - qerror_report(ERROR_CLASS_GENERIC_ERROR,
> - "Failed to create snapshot for device '%s':
> %s",
> - bdrv_get_device_name(bs1),
> - error_get_pretty(local_err));
> + error_setg(errp, "Failed to create snapshot for "
> + "device '%s': %s", bdrv_get_device_name(bs1),
> + error_get_pretty(local_err));
> error_free(local_err);
> + goto the_end;
> }
> }
> }
>
> + info = g_malloc0(sizeof(SnapshotInfo));
> + info->id = g_strdup(sn->id_str);
> + info->name = g_strdup(sn->name);
> + info->date_nsec = sn->date_nsec;
> + info->date_sec = sn->date_sec;
> + info->vm_state_size = vm_state_size;
> + info->vm_clock_nsec = sn->vm_clock_nsec % 1000000000;
> + info->vm_clock_sec = sn->vm_clock_nsec / 1000000000;
You could consider using a compound literal for better readability:
info = g_malloc(...);
*info = (SnapshotInfo) {
.id = g_strdup(sn->id_str),
.name = g_strdup(sn->name),
.date_nsec = sn->date_nsec,
...
};
> the_end:
> if (saved_vm_running)
> vm_start();
> +
> + return info;
> }
Kevin
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: [Qemu-devel] [PATCH v2 11/12] qapi: Convert savevm,
Kevin Wolf <=