[libvirt] [PATCH 2/4] snapshot: add 'virsh snapshot-info'
Osier Yang
jyang at redhat.com
Mon Jun 11 06:49:08 UTC 2012
On 2012年05月25日 11:33, Eric Blake wrote:
> Expose the recent API additions in virsh. Borrows ideas from 'dominfo'
> for the general type of information to display. Output looks like:
>
> $ tools/virsh snapshot-info fedora-local tmp
> Name: tmp
> Domain: fedora-local
> Current: no
> State: disk-snapshot
> Parent: -
> Children: 1
> Descendants: 2
> Metadata: yes
>
> possibly with fewer lines when talking to older servers.
>
> * tools/virsh.c (cmdSnapshotInfo): New command.
> * tools/virsh.pod (snapshot-info): Document it.
>
> ---
> tools/virsh.c | 125 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
> tools/virsh.pod | 5 ++
> 2 files changed, 130 insertions(+), 0 deletions(-)
>
> diff --git a/tools/virsh.c b/tools/virsh.c
> index ffe6ed2..6a85338 100644
> --- a/tools/virsh.c
> +++ b/tools/virsh.c
> @@ -16601,6 +16601,129 @@ cleanup:
> }
>
> /*
> + * "snapshot-info" command
> + */
> +static const vshCmdInfo info_snapshot_info[] = {
> + {"help", N_("snapshot information")},
> + {"desc", N_("Returns basic information about a snapshot.")},
> + {NULL, NULL}
> +};
> +
> +static const vshCmdOptDef opts_snapshot_info[] = {
> + {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
> + {"snapshotname", VSH_OT_DATA, 0, N_("snapshot name")},
> + {"current", VSH_OT_BOOL, 0, N_("info on current snapshot")},
> + {NULL, 0, 0, NULL}
> +};
> +
> +static bool
> +cmdSnapshotInfo(vshControl *ctl, const vshCmd *cmd)
> +{
> + virDomainPtr dom;
> + virDomainSnapshotPtr snapshot = NULL;
> + const char *name;
> + char *doc = NULL;
> + char *tmp;
> + char *parent = NULL;
> + bool ret = false;
> + int count;
> + unsigned int flags;
> + int current;
> + int metadata;
> +
> + if (!vshConnectionUsability(ctl, ctl->conn))
> + return false;
> +
> + dom = vshCommandOptDomain(ctl, cmd, NULL);
> + if (dom == NULL)
> + return false;
> +
> + if (vshLookupSnapshot(ctl, cmd, "snapshotname", true, dom,
> +&snapshot,&name)< 0)
> + goto cleanup;
> +
> + vshPrint(ctl, "%-15s %s\n", _("Name:"), name);
> + vshPrint(ctl, "%-15s %s\n", _("Domain:"), virDomainGetName(dom));
> +
> + /* Determine if snapshot is current; this is useful enough that we
> + * attempt a fallback. */
> + current = virDomainSnapshotIsCurrent(snapshot, 0);
> + if (current< 0) {
> + virDomainSnapshotPtr other = virDomainSnapshotCurrent(dom, 0);
> +
> + virResetLastError();
> + current = 0;
> + if (other) {
> + if (STREQ(name, virDomainSnapshotGetName(other)))
> + current = 1;
> + virDomainSnapshotFree(other);
> + }
> + }
> + vshPrint(ctl, "%-15s %s\n", _("Current:"),
> + current> 0 ? _("yes") : _("no"));
> +
> + /* Get the XML configuration of the snapshot to determine the
> + * state of the machine at the time of the snapshot. */
> + doc = virDomainSnapshotGetXMLDesc(snapshot, 0);
> + if (!doc)
> + goto cleanup;
> +
> + tmp = strstr(doc, "<state>");
> + if (!tmp) {
> + vshError(ctl, "%s",
> + _("unexpected problem reading snapshot xml"));
> + goto cleanup;
> + }
> + tmp += strlen("<state>");
> + vshPrint(ctl, "%-15s %.*s\n", _("State:"),
> + (int) (strchr(tmp, '<') - tmp), tmp);
> +
> + if (vshGetSnapshotParent(ctl, snapshot,&parent)< 0)
> + goto cleanup;
> + vshPrint(ctl, "%-15s %s\n", _("Parent:"), parent ? parent : "-");
> +
> + /* Children, Descendants. After this point, the fallback to
> + * compute children is too expensive, so we gracefully quit if the
> + * APIs don't exist. */
> + if (ctl->useSnapshotOld) {
> + ret = true;
> + goto cleanup;
> + }
> + flags = 0;
> + count = virDomainSnapshotNumChildren(snapshot, 0);
> + if (count< 0)
> + goto cleanup;
> + vshPrint(ctl, "%-15s %d\n", _("Children:"), count);
> + flags = VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS;
> + count = virDomainSnapshotNumChildren(snapshot, flags);
> + if (count< 0)
> + goto cleanup;
> + vshPrint(ctl, "%-15s %d\n", _("Descendants:"), count);
> +
> + /* Metadata; the fallback here relies on the fact that metadata
> + * used to have an all-or-nothing effect on snapshot count. */
> + metadata = virDomainSnapshotHasMetadata(snapshot, 0);
> + if (metadata< 0) {
> + virResetLastError();
> + count = virDomainSnapshotNum(dom,
> + VIR_DOMAIN_SNAPSHOT_LIST_METADATA);
> + metadata = count != 0;
> + }
> + vshPrint(ctl, "%-15s %s\n", _("Metadata:"),
> + metadata> 0 ? _("yes") : _("no"));
> +
> + ret = true;
> +
> +cleanup:
> + VIR_FREE(doc);
> + VIR_FREE(parent);
> + if (snapshot)
> + virDomainSnapshotFree(snapshot);
> + virDomainFree(dom);
> + return ret;
> +}
> +
> +/*
> * "snapshot-list" command
> */
> static const vshCmdInfo info_snapshot_list[] = {
> @@ -17702,6 +17825,8 @@ static const vshCmdDef snapshotCmds[] = {
> info_snapshot_dumpxml, 0},
> {"snapshot-edit", cmdSnapshotEdit, opts_snapshot_edit,
> info_snapshot_edit, 0},
> + {"snapshot-info", cmdSnapshotInfo, opts_snapshot_info,
> + info_snapshot_info, 0},
> {"snapshot-list", cmdSnapshotList, opts_snapshot_list,
> info_snapshot_list, 0},
> {"snapshot-parent", cmdSnapshotParent, opts_snapshot_parent,
> diff --git a/tools/virsh.pod b/tools/virsh.pod
> index ef71717..6553825 100644
> --- a/tools/virsh.pod
> +++ b/tools/virsh.pod
> @@ -2504,6 +2504,11 @@ a snapshot name must be done with care, since the contents of some
> snapshots, such as internal snapshots within a single qcow2 file, are
> accessible only from the original name.
>
> +=item B<snapshot-info> I<domain> {I<snapshot> | I<--current>}
> +
> +Output basic information about a named<snapshot>, or the current snapshot
> +with I<--current>.
> +
> =item B<snapshot-list> I<domain> [{I<--parent> | I<--roots> | I<--tree>}]
> [{[I<--from>] B<snapshot> | I<--current>} [I<--descendants>]]
> [I<--metadata>] [I<--leaves>]
ACK
Osier
More information about the libvir-list
mailing list