mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-08 12:41:29 +00:00
snapshot: add 'virsh snapshot-info'
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.
This commit is contained in:
parent
a0ac7450d9
commit
757c47635d
125
tools/virsh.c
125
tools/virsh.c
@ -16567,6 +16567,129 @@ cleanup:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "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, flags);
|
||||||
|
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) {
|
||||||
|
metadata = virDomainSnapshotNum(dom,
|
||||||
|
VIR_DOMAIN_SNAPSHOT_LIST_METADATA);
|
||||||
|
virResetLastError();
|
||||||
|
}
|
||||||
|
if (metadata >= 0)
|
||||||
|
vshPrint(ctl, "%-15s %s\n", _("Metadata:"),
|
||||||
|
metadata ? _("yes") : _("no"));
|
||||||
|
|
||||||
|
ret = true;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
VIR_FREE(doc);
|
||||||
|
VIR_FREE(parent);
|
||||||
|
if (snapshot)
|
||||||
|
virDomainSnapshotFree(snapshot);
|
||||||
|
virDomainFree(dom);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "snapshot-list" command
|
* "snapshot-list" command
|
||||||
*/
|
*/
|
||||||
@ -17661,6 +17784,8 @@ static const vshCmdDef snapshotCmds[] = {
|
|||||||
info_snapshot_dumpxml, 0},
|
info_snapshot_dumpxml, 0},
|
||||||
{"snapshot-edit", cmdSnapshotEdit, opts_snapshot_edit,
|
{"snapshot-edit", cmdSnapshotEdit, opts_snapshot_edit,
|
||||||
info_snapshot_edit, 0},
|
info_snapshot_edit, 0},
|
||||||
|
{"snapshot-info", cmdSnapshotInfo, opts_snapshot_info,
|
||||||
|
info_snapshot_info, 0},
|
||||||
{"snapshot-list", cmdSnapshotList, opts_snapshot_list,
|
{"snapshot-list", cmdSnapshotList, opts_snapshot_list,
|
||||||
info_snapshot_list, 0},
|
info_snapshot_list, 0},
|
||||||
{"snapshot-parent", cmdSnapshotParent, opts_snapshot_parent,
|
{"snapshot-parent", cmdSnapshotParent, opts_snapshot_parent,
|
||||||
|
@ -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
|
snapshots, such as internal snapshots within a single qcow2 file, are
|
||||||
accessible only from the original name.
|
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>}]
|
=item B<snapshot-list> I<domain> [{I<--parent> | I<--roots> | I<--tree>}]
|
||||||
[{[I<--from>] B<snapshot> | I<--current>} [I<--descendants>]]
|
[{[I<--from>] B<snapshot> | I<--current>} [I<--descendants>]]
|
||||||
[I<--metadata>] [I<--leaves>]
|
[I<--metadata>] [I<--leaves>]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user